1
0
mirror of https://github.com/videojs/video.js.git synced 2025-02-08 12:05:47 +02:00

feat: split overrideNative method into separate methods (#5107)

Split overrideNative method into one for Audio and Video. Fixes issues with differing track support in IE11.
This commit is contained in:
Oshin Karamian 2018-04-19 20:11:11 -04:00 committed by Gary Katsevman
parent 97db94e8a6
commit 083a86c363
3 changed files with 123 additions and 100 deletions

View File

@ -201,40 +201,124 @@ class Html5 extends Tech {
} }
/** /**
* Attempt to force override of native audio/video tracks. * Attempt to force override of tracks for the given type
* *
* @param {String} type - Track type to override, possible values include 'Audio',
* 'Video', and 'Text'.
* @param {Boolean} override - If set to true native audio/video will be overridden, * @param {Boolean} override - If set to true native audio/video will be overridden,
* otherwise native audio/video will potentially be used. * otherwise native audio/video will potentially be used.
* @private
*/ */
overrideNativeTracks(override) { overrideNative_(type, override) {
// If there is no behavioral change don't add/remove listeners // If there is no behavioral change don't add/remove listeners
if (override !== (this.featuresNativeAudioTracks && this.featuresNativeVideoTracks)) { if (override !== this[`featuresNative${type}Tracks`]) {
return; return;
} }
if (this.audioTracksListeners_) { const lowerCaseType = type.toLowerCase();
Object.keys(this.audioTracksListeners_).forEach((eventName) => {
const elTracks = this.el().audioTracks;
elTracks.removeEventListener(eventName, this.audioTracksListeners_[eventName]); if (this[`${lowerCaseType}TracksListeners_`]) {
Object.keys(this[`${lowerCaseType}TracksListeners_`]).forEach((eventName) => {
const elTracks = this.el()[`${lowerCaseType}Tracks`];
elTracks.removeEventListener(eventName, this[`${lowerCaseType}TracksListeners_`][eventName]);
}); });
} }
if (this.videoTracksListeners_) { this[`featuresNative${type}Tracks`] = !override;
Object.keys(this.videoTracksListeners_).forEach((eventName) => { this[`${lowerCaseType}TracksListeners_`] = null;
const elTracks = this.el().videoTracks;
elTracks.removeEventListener(eventName, this.videoTracksListeners_[eventName]); this.proxyNativeTracksForType_(lowerCaseType);
}); }
/**
* Attempt to force override of native audio tracks.
*
* @param {Boolean} override - If set to true native audio will be overridden,
* otherwise native audio will potentially be used.
*/
overrideNativeAudioTracks(override) {
this.overrideNative_('Audio', override);
}
/**
* Attempt to force override of native video tracks.
*
* @param {Boolean} override - If set to true native video will be overridden,
* otherwise native video will potentially be used.
*/
overrideNativeVideoTracks(override) {
this.overrideNative_('Video', override);
}
/**
* Proxy native track list events for the given type to our track
* lists if the browser we are playing in supports that type of track list.
*
* @param {string} name - Track type; values include 'audio', 'video', and 'text'
* @private
*/
proxyNativeTracksForType_(name) {
const props = TRACK_TYPES[name];
const elTracks = this.el()[props.getterName];
const techTracks = this[props.getterName]();
if (!this[`featuresNative${props.capitalName}Tracks`] ||
!elTracks ||
!elTracks.addEventListener) {
return;
} }
const listeners = {
change(e) {
techTracks.trigger({
type: 'change',
target: techTracks,
currentTarget: techTracks,
srcElement: techTracks
});
},
addtrack(e) {
techTracks.addTrack(e.track);
},
removetrack(e) {
techTracks.removeTrack(e.track);
}
};
const removeOldTracks = function() {
const removeTracks = [];
this.featuresNativeVideoTracks = !override; for (let i = 0; i < techTracks.length; i++) {
this.featuresNativeAudioTracks = !override; let found = false;
this.audioTracksListeners_ = null; for (let j = 0; j < elTracks.length; j++) {
this.videoTracksListeners_ = null; if (elTracks[j] === techTracks[i]) {
found = true;
break;
}
}
this.proxyNativeTracks_(); if (!found) {
removeTracks.push(techTracks[i]);
}
}
while (removeTracks.length) {
techTracks.removeTrack(removeTracks.shift());
}
};
this[props.getterName + 'Listeners_'] = listeners;
Object.keys(listeners).forEach((eventName) => {
const listener = listeners[eventName];
elTracks.addEventListener(eventName, listener);
this.on('dispose', (e) => elTracks.removeEventListener(eventName, listener));
});
// Remove (native) tracks that are not used anymore
this.on('loadstart', removeOldTracks);
this.on('dispose', (e) => this.off('loadstart', removeOldTracks));
} }
/** /**
@ -245,68 +329,8 @@ class Html5 extends Tech {
*/ */
proxyNativeTracks_() { proxyNativeTracks_() {
TRACK_TYPES.names.forEach((name) => { TRACK_TYPES.names.forEach((name) => {
const props = TRACK_TYPES[name]; this.proxyNativeTracksForType_(name);
const elTracks = this.el()[props.getterName];
const techTracks = this[props.getterName]();
if (!this[`featuresNative${props.capitalName}Tracks`] ||
!elTracks ||
!elTracks.addEventListener) {
return;
}
const listeners = {
change(e) {
techTracks.trigger({
type: 'change',
target: techTracks,
currentTarget: techTracks,
srcElement: techTracks
});
},
addtrack(e) {
techTracks.addTrack(e.track);
},
removetrack(e) {
techTracks.removeTrack(e.track);
}
};
const removeOldTracks = function() {
const removeTracks = [];
for (let i = 0; i < techTracks.length; i++) {
let found = false;
for (let j = 0; j < elTracks.length; j++) {
if (elTracks[j] === techTracks[i]) {
found = true;
break;
}
}
if (!found) {
removeTracks.push(techTracks[i]);
}
}
while (removeTracks.length) {
techTracks.removeTrack(removeTracks.shift());
}
};
this[props.getterName + 'Listeners_'] = listeners;
Object.keys(listeners).forEach((eventName) => {
const listener = listeners[eventName];
elTracks.addEventListener(eventName, listener);
this.on('dispose', (e) => elTracks.removeEventListener(eventName, listener));
});
// Remove (native) tracks that are not used anymore
this.on('loadstart', removeOldTracks);
this.on('dispose', (e) => this.off('loadstart', removeOldTracks));
}); });
} }
/** /**

View File

@ -786,14 +786,24 @@ class Tech extends Component {
setPlaysinline() {} setPlaysinline() {}
/** /**
* Attempt to force override of native audio.video tracks. * Attempt to force override of native audio tracks.
* *
* @param {Boolean} override - If set to true native audio/video will be overridden, * @param {Boolean} override - If set to true native audio will be overridden,
* otherwise native audio/video will potentially be used. * otherwise native audio will potentially be used.
* *
* @abstract * @abstract
*/ */
overrideNativeTracks() {} overrideNativeAudioTracks() {}
/**
* Attempt to force override of native video tracks.
*
* @param {Boolean} override - If set to true native video will be overridden,
* otherwise native video will potentially be used.
*
* @abstract
*/
overrideNativeVideoTracks() {}
/* /*
* Check if the tech can support the given mime-type. * Check if the tech can support the given mime-type.

View File

@ -550,15 +550,10 @@ if (Html5.supportsNativeAudioTracks()) {
rems.push({ type, fn }); rems.push({ type, fn });
} }
}; };
const vt = {
length: 0,
addEventListener: (type, fn) => null,
removeEventListener: (type, fn) => null
};
const el = document.createElement('div'); const el = document.createElement('div');
el.audioTracks = at; el.audioTracks = at;
el.videoTracks = vt;
const htmlTech = new Html5({el}); const htmlTech = new Html5({el});
@ -567,21 +562,21 @@ if (Html5.supportsNativeAudioTracks()) {
assert.equal(rems.length, 0, assert.equal(rems.length, 0,
'no listeners should be removed'); 'no listeners should be removed');
htmlTech.overrideNativeTracks(true); htmlTech.overrideNativeAudioTracks(true);
assert.equal(adds.length, 3, assert.equal(adds.length, 3,
'should not have added additional listeners'); 'should not have added additional listeners');
assert.equal(rems.length, 3, assert.equal(rems.length, 3,
'should have removed previous three listeners'); 'should have removed previous three listeners');
htmlTech.overrideNativeTracks(true); htmlTech.overrideNativeAudioTracks(true);
assert.equal(adds.length, 3, assert.equal(adds.length, 3,
'no state change so do not add listeners'); 'no state change so do not add listeners');
assert.equal(rems.length, 3, assert.equal(rems.length, 3,
'no state change so do not remove listeners'); 'no state change so do not remove listeners');
htmlTech.overrideNativeTracks(false); htmlTech.overrideNativeAudioTracks(false);
assert.equal(adds.length, 6, assert.equal(adds.length, 6,
'should add listeners because native tracks should be proxied'); 'should add listeners because native tracks should be proxied');
@ -673,14 +668,8 @@ if (Html5.supportsNativeVideoTracks()) {
rems.push({ type, fn }); rems.push({ type, fn });
} }
}; };
const at = {
length: 0,
addEventListener: (type, fn) => null,
removeEventListener: (type, fn) => null
};
const el = document.createElement('div'); const el = document.createElement('div');
el.audioTracks = at;
el.videoTracks = vt; el.videoTracks = vt;
const htmlTech = new Html5({el}); const htmlTech = new Html5({el});
@ -690,21 +679,21 @@ if (Html5.supportsNativeVideoTracks()) {
assert.equal(rems.length, 0, assert.equal(rems.length, 0,
'no listeners should be removed'); 'no listeners should be removed');
htmlTech.overrideNativeTracks(true); htmlTech.overrideNativeVideoTracks(true);
assert.equal(adds.length, 3, assert.equal(adds.length, 3,
'should not have added additional listeners'); 'should not have added additional listeners');
assert.equal(rems.length, 3, assert.equal(rems.length, 3,
'should have removed previous three listeners'); 'should have removed previous three listeners');
htmlTech.overrideNativeTracks(true); htmlTech.overrideNativeVideoTracks(true);
assert.equal(adds.length, 3, assert.equal(adds.length, 3,
'no state change so do not add listeners'); 'no state change so do not add listeners');
assert.equal(rems.length, 3, assert.equal(rems.length, 3,
'no state change so do not remove listeners'); 'no state change so do not remove listeners');
htmlTech.overrideNativeTracks(false); htmlTech.overrideNativeVideoTracks(false);
assert.equal(adds.length, 6, assert.equal(adds.length, 6,
'should add listeners because native tracks should be proxied'); 'should add listeners because native tracks should be proxied');