Skip to content

Commit 22bbbc9

Browse files
OshinKaramiangkatsev
authored andcommitted
feat: add tech method to allow override native audio and video (videojs#5074)
1 parent 1069e7f commit 22bbbc9

File tree

3 files changed

+160
-1
lines changed

3 files changed

+160
-1
lines changed

src/js/tech/html5.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,43 @@ class Html5 extends Tech {
200200
});
201201
}
202202

203+
/**
204+
* Attempt to force override of native audio/video tracks.
205+
*
206+
* @param {Boolean} override - If set to true native audio/video will be overridden,
207+
* otherwise native audio/video will potentially be used.
208+
*/
209+
overrideNativeTracks(override) {
210+
// If there is no behavioral change don't add/remove listeners
211+
if (override !== (this.featuresNativeAudioTracks && this.featuresNativeVideoTracks)) {
212+
return;
213+
}
214+
215+
if (this.audioTracksListeners_) {
216+
Object.keys(this.audioTracksListeners_).forEach((eventName) => {
217+
const elTracks = this.el().audioTracks;
218+
219+
elTracks.removeEventListener(eventName, this.audioTracksListeners_[eventName]);
220+
});
221+
}
222+
223+
if (this.videoTracksListeners_) {
224+
Object.keys(this.videoTracksListeners_).forEach((eventName) => {
225+
const elTracks = this.el().videoTracks;
226+
227+
elTracks.removeEventListener(eventName, this.videoTracksListeners_[eventName]);
228+
});
229+
}
230+
231+
this.featuresNativeVideoTracks = !override;
232+
this.featuresNativeAudioTracks = !override;
233+
234+
this.audioTracksListeners_ = null;
235+
this.videoTracksListeners_ = null;
236+
237+
this.proxyNativeTracks_();
238+
}
239+
203240
/**
204241
* Proxy all native track list events to our track lists if the browser we are playing
205242
* in supports that type of track list.
@@ -256,6 +293,8 @@ class Html5 extends Tech {
256293
}
257294
};
258295

296+
this[props.getterName + 'Listeners_'] = listeners;
297+
259298
Object.keys(listeners).forEach((eventName) => {
260299
const listener = listeners[eventName];
261300

src/js/tech/tech.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,16 @@ class Tech extends Component {
785785
*/
786786
setPlaysinline() {}
787787

788+
/**
789+
* Attempt to force override of native audio.video tracks.
790+
*
791+
* @param {Boolean} override - If set to true native audio/video will be overridden,
792+
* otherwise native audio/video will potentially be used.
793+
*
794+
* @abstract
795+
*/
796+
overrideNativeTracks() {}
797+
788798
/*
789799
* Check if the tech can support the given mime-type.
790800
*
@@ -1219,7 +1229,7 @@ Tech.withSourceHandlers = function(_Tech) {
12191229
if (_Tech.nativeSourceHandler) {
12201230
sh = _Tech.nativeSourceHandler;
12211231
} else {
1222-
log.error('No source hander found for the current source.');
1232+
log.error('No source handler found for the current source.');
12231233
}
12241234
}
12251235

test/unit/tech/html5.test.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,61 @@ if (Html5.supportsNativeAudioTracks()) {
535535
assert.equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
536536
assert.equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
537537
});
538+
539+
QUnit.test('should use overrideNativeTracks on audio correctly', function(assert) {
540+
assert.expect(8);
541+
542+
const adds = [];
543+
const rems = [];
544+
const at = {
545+
length: 0,
546+
addEventListener: (type, fn) => {
547+
adds.push({ type, fn });
548+
},
549+
removeEventListener: (type, fn) => {
550+
rems.push({ type, fn });
551+
}
552+
};
553+
const vt = {
554+
length: 0,
555+
addEventListener: (type, fn) => null,
556+
removeEventListener: (type, fn) => null
557+
};
558+
const el = document.createElement('div');
559+
560+
el.audioTracks = at;
561+
el.videoTracks = vt;
562+
563+
const htmlTech = new Html5({el});
564+
565+
assert.equal(adds.length, 3,
566+
'should have added change, remove, add listeners');
567+
assert.equal(rems.length, 0,
568+
'no listeners should be removed');
569+
570+
htmlTech.overrideNativeTracks(true);
571+
572+
assert.equal(adds.length, 3,
573+
'should not have added additional listeners');
574+
assert.equal(rems.length, 3,
575+
'should have removed previous three listeners');
576+
577+
htmlTech.overrideNativeTracks(true);
578+
579+
assert.equal(adds.length, 3,
580+
'no state change so do not add listeners');
581+
assert.equal(rems.length, 3,
582+
'no state change so do not remove listeners');
583+
584+
htmlTech.overrideNativeTracks(false);
585+
586+
assert.equal(adds.length, 6,
587+
'should add listeners because native tracks should be proxied');
588+
assert.equal(rems.length, 3,
589+
'should not remove listeners because there where none added on previous state');
590+
591+
htmlTech.dispose();
592+
});
538593
}
539594

540595
if (Html5.supportsNativeVideoTracks()) {
@@ -603,6 +658,61 @@ if (Html5.supportsNativeVideoTracks()) {
603658
assert.equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
604659
assert.equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
605660
});
661+
662+
QUnit.test('should use overrideNativeTracks on video correctly', function(assert) {
663+
assert.expect(8);
664+
665+
const adds = [];
666+
const rems = [];
667+
const vt = {
668+
length: 0,
669+
addEventListener: (type, fn) => {
670+
adds.push({ type, fn });
671+
},
672+
removeEventListener: (type, fn) => {
673+
rems.push({ type, fn });
674+
}
675+
};
676+
const at = {
677+
length: 0,
678+
addEventListener: (type, fn) => null,
679+
removeEventListener: (type, fn) => null
680+
};
681+
const el = document.createElement('div');
682+
683+
el.audioTracks = at;
684+
el.videoTracks = vt;
685+
686+
const htmlTech = new Html5({el});
687+
688+
assert.equal(adds.length, 3,
689+
'should have added change, remove, add listeners');
690+
assert.equal(rems.length, 0,
691+
'no listeners should be removed');
692+
693+
htmlTech.overrideNativeTracks(true);
694+
695+
assert.equal(adds.length, 3,
696+
'should not have added additional listeners');
697+
assert.equal(rems.length, 3,
698+
'should have removed previous three listeners');
699+
700+
htmlTech.overrideNativeTracks(true);
701+
702+
assert.equal(adds.length, 3,
703+
'no state change so do not add listeners');
704+
assert.equal(rems.length, 3,
705+
'no state change so do not remove listeners');
706+
707+
htmlTech.overrideNativeTracks(false);
708+
709+
assert.equal(adds.length, 6,
710+
'should add listeners because native tracks should be proxied');
711+
assert.equal(rems.length, 3,
712+
'should not remove listeners because there where none added on previous state');
713+
714+
htmlTech.dispose();
715+
});
606716
}
607717

608718
QUnit.test('should always return currentSource_ if set', function(assert) {

0 commit comments

Comments
 (0)