Skip to content

Commit

Permalink
@brandonocasey added audio and video track support. closes #3173
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey authored and misteroneill committed Apr 22, 2016
1 parent 18cdf08 commit 2e2dbde
Show file tree
Hide file tree
Showing 32 changed files with 2,049 additions and 406 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CHANGELOG
* @gkatsev Use fonts 2.0 that do not require wrapping codepoints ([view](https://github.com/videojs/video.js/pull/3252))
* @chrisauclair Make controls visible for accessibility reasons ([view](https://github.com/videojs/video.js/pull/3237))
* @gkatsev updated text track documentation and crossorigin warning. Fixes #1888, #1958, #2628, #3202 ([view](https://github.com/videojs/video.js/pull/3256))
* @BrandonOCasey added audio and video track support ([view](https://github.com/videojs/video.js/pull/3173))

--------------------

Expand Down
54 changes: 47 additions & 7 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import safeParseTuple from 'safe-json-parse/tuple';
import assign from 'object.assign';
import mergeOptions from './utils/merge-options.js';
import textTrackConverter from './tracks/text-track-list-converter.js';
import AudioTrackList from './tracks/audio-track-list.js';
import VideoTrackList from './tracks/video-track-list.js';

// Include required child components (importing also registers them)
import MediaLoader from './tech/loader.js';
Expand Down Expand Up @@ -555,7 +557,9 @@ class Player extends Component {
'source': source,
'playerId': this.id(),
'techId': `${this.id()}_${techName}_api`,
'videoTracks': this.videoTracks_,
'textTracks': this.textTracks_,
'audioTracks': this.audioTracks_,
'autoplay': this.options_.autoplay,
'preload': this.options_.preload,
'loop': this.options_.loop,
Expand Down Expand Up @@ -648,7 +652,9 @@ class Player extends Component {
*/
unloadTech_() {
// Save the current text tracks so that we can reuse the same text tracks with the next tech
this.videoTracks_ = this.videoTracks();
this.textTracks_ = this.textTracks();
this.audioTracks_ = this.audioTracks();
this.textTracksJson_ = textTrackConverter.textTracksToJson(this.tech_);

this.isReady_ = false;
Expand Down Expand Up @@ -2509,12 +2515,48 @@ class Player extends Component {
}

/**
* Text tracks are tracks of timed text events.
* Captions - text displayed over the video for the hearing impaired
* Subtitles - text displayed over the video for those who don't understand language in the video
* Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
* Descriptions - audio descriptions that are read back to the user by a screen reading device
* Get a video track list
* @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
*
* @return {VideoTrackList} thes current video track list
* @method videoTracks
*/
videoTracks() {
// if we have not yet loadTech_, we create videoTracks_
// these will be passed to the tech during loading
if (!this.tech_) {
this.videoTracks_ = this.videoTracks_ || new VideoTrackList();
return this.videoTracks_;
}

return this.tech_.videoTracks();
}

/**
* Get an audio track list
* @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
*
* @return {AudioTrackList} thes current audio track list
* @method audioTracks
*/
audioTracks() {
// if we have not yet loadTech_, we create videoTracks_
// these will be passed to the tech during loading
if (!this.tech_) {
this.audioTracks_ = this.audioTracks_ || new AudioTrackList();
return this.audioTracks_;
}

return this.tech_.audioTracks();
}

/*
* Text tracks are tracks of timed text events.
* Captions - text displayed over the video for the hearing impaired
* Subtitles - text displayed over the video for those who don't understand language in the video
* Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
* Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
*/

/**
* Get an array of associated text tracks. captions, subtitles, chapters, descriptions
Expand Down Expand Up @@ -2609,8 +2651,6 @@ class Player extends Component {
// initialTime: function(){ return this.techCall_('initialTime'); },
// startOffsetTime: function(){ return this.techCall_('startOffsetTime'); },
// played: function(){ return this.techCall_('played'); },
// videoTracks: function(){ return this.techCall_('videoTracks'); },
// audioTracks: function(){ return this.techCall_('audioTracks'); },
// defaultPlaybackRate: function(){ return this.techCall_('defaultPlaybackRate'); },
// defaultMuted: function(){ return this.techCall_('defaultMuted'); }

Expand Down
2 changes: 1 addition & 1 deletion src/js/tech/flash.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ class Flash extends Tech {
// Create setters and getters for attributes
const _api = Flash.prototype;
const _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
const _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoTracks,audioTracks,videoWidth,videoHeight'.split(',');
const _readOnly = 'networkState,readyState,initialTime,duration,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');

function _createSetter(attr){
var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
Expand Down
121 changes: 104 additions & 17 deletions src/js/tech/html5.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import document from 'global/document';
import window from 'global/window';
import assign from 'object.assign';
import mergeOptions from '../utils/merge-options.js';
import toTitleCase from '../utils/to-title-case.js';

/**
* HTML5 Media Controller - Wrapper for HTML5 Media API
Expand Down Expand Up @@ -78,6 +79,24 @@ class Html5 extends Tech {
}
}

let trackTypes = ['audio', 'video'];

// ProxyNativeTextTracks
trackTypes.forEach((type) => {
let capitalType = toTitleCase(type);

if (!this[`featuresNative${capitalType}Tracks`]) {
return;
}
let tl = this.el()[`${type}Tracks`];

if (tl && tl.addEventListener) {
tl.addEventListener('change', Fn.bind(this, this[`handle${capitalType}TrackChange_`]));
tl.addEventListener('addtrack', Fn.bind(this, this[`handle${capitalType}TrackAdd_`]));
tl.addEventListener('removetrack', Fn.bind(this, this[`handle${capitalType}TrackRemove_`]));
}
});

if (this.featuresNativeTextTracks) {
if (crossoriginTracks) {
log.warn(tsml`Text Tracks are being loaded from another origin but the crossorigin attribute isn't used.
Expand Down Expand Up @@ -109,25 +128,20 @@ class Html5 extends Tech {
* @method dispose
*/
dispose() {
let tt = this.el().textTracks;
let emulatedTt = this.textTracks();

// remove native event listeners
if (tt && tt.removeEventListener) {
tt.removeEventListener('change', this.handleTextTrackChange_);
tt.removeEventListener('addtrack', this.handleTextTrackAdd_);
tt.removeEventListener('removetrack', this.handleTextTrackRemove_);
}

// clearout the emulated text track list.
let i = emulatedTt.length;

while (i--) {
emulatedTt.removeTrack_(emulatedTt[i]);
}

// Un-ProxyNativeTracks
['audio', 'video', 'text'].forEach((type) => {
let capitalType = toTitleCase(type);
let tl = this.el_[`${type}Tracks`];

if (tl && tl.removeEventListener) {
tl.removeEventListener('change', this[`handle${capitalType}TrackChange_`]);
tl.removeEventListener('addtrack', this[`handle${capitalType}TrackAdd_`]);
tl.removeEventListener('removetrack', this[`handle${capitalType}TrackRemove_`]);
}
});

Html5.disposeMediaElement(this.el_);
// tech will handle clearing of the emulated track list
super.dispose();
}

Expand Down Expand Up @@ -303,6 +317,43 @@ class Html5 extends Tech {
this.textTracks().removeTrack_(e.track);
}

handleVideoTrackChange_(e) {
let vt = this.videoTracks();
this.videoTracks().trigger({
type: 'change',
target: vt,
currentTarget: vt,
srcElement: vt
});
}

handleVideoTrackAdd_(e) {
this.videoTracks().addTrack_(e.track);
}

handleVideoTrackRemove_(e) {
this.videoTracks().removeTrack_(e.track);
}

handleAudioTrackChange_(e) {
let audioTrackList = this.audioTracks();
this.audioTracks().trigger({
type: 'change',
target: audioTrackList,
currentTarget: audioTrackList,
srcElement: audioTrackList
});
}

handleAudioTrackAdd_(e) {
this.audioTracks().addTrack_(e.track);
}

handleAudioTrackRemove_(e) {
this.audioTracks().removeTrack_(e.track);
}


/**
* Play for html5 tech
*
Expand Down Expand Up @@ -989,6 +1040,27 @@ Html5.supportsNativeTextTracks = function() {
return supportsTextTracks;
};

/*
* Check to see if native video tracks are supported by this browser/device
*
* @return {Boolean}
*/
Html5.supportsNativeVideoTracks = function() {
let supportsVideoTracks = !!Html5.TEST_VID.videoTracks;
return supportsVideoTracks;
};

/*
* Check to see if native audio tracks are supported by this browser/device
*
* @return {Boolean}
*/
Html5.supportsNativeAudioTracks = function() {
let supportsAudioTracks = !!Html5.TEST_VID.audioTracks;
return supportsAudioTracks;
};


/**
* An array of events available on the Html5 tech.
*
Expand Down Expand Up @@ -1062,6 +1134,21 @@ Html5.prototype['featuresProgressEvents'] = true;
*/
Html5.prototype['featuresNativeTextTracks'] = Html5.supportsNativeTextTracks();

/**
* Sets the tech's status on native text track support
*
* @type {Boolean}
*/
Html5.prototype['featuresNativeVideoTracks'] = Html5.supportsNativeVideoTracks();

/**
* Sets the tech's status on native audio track support
*
* @type {Boolean}
*/
Html5.prototype['featuresNativeAudioTracks'] = Html5.supportsNativeAudioTracks();


// HTML5 Feature detection and Device Fixes --------------------------------- //
let canPlayType;
const mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
Expand Down
Loading

0 comments on commit 2e2dbde

Please sign in to comment.