diff --git a/src/js/player.js b/src/js/player.js index b086b16f78..dc4e58a8cb 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -1823,7 +1823,7 @@ class Player extends Component { let foundSourceAndTech; let flip = (fn) => (a, b) => fn(b, a); let finder = ([techName, tech], source) => { - if (tech.canPlaySource(source)) { + if (tech.canPlaySource(source, this.options_[techName.toLowerCase()])) { return {source: source, tech: techName}; } }; @@ -1898,7 +1898,7 @@ class Player extends Component { } else if (source instanceof Object) { // check if the source has a type and the loaded tech cannot play the source // if there's no type we'll just try the current tech - if (source.type && !currentTech.canPlaySource(source)) { + if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) { // create a source list with the current source and send through // the tech loop to check for a compatible technology this.sourceList_([source]); diff --git a/src/js/tech/flash-rtmp.js b/src/js/tech/flash-rtmp.js index ff1864822c..4b7f4d3872 100644 --- a/src/js/tech/flash-rtmp.js +++ b/src/js/tech/flash-rtmp.js @@ -75,9 +75,10 @@ function FlashRtmpDecorator(Flash) { /** * Check if Flash can handle the source natively * @param {Object} source The source object + * @param {Object} options The options passed to the tech * @return {String} 'probably', 'maybe', or '' (empty string) */ - Flash.rtmpSourceHandler.canHandleSource = function(source){ + Flash.rtmpSourceHandler.canHandleSource = function(source, options){ let can = Flash.rtmpSourceHandler.canPlayType(source.type); if (can) { diff --git a/src/js/tech/flash.js b/src/js/tech/flash.js index fb1b13b0cc..11bb2ceffd 100644 --- a/src/js/tech/flash.js +++ b/src/js/tech/flash.js @@ -369,9 +369,10 @@ Flash.nativeSourceHandler.canPlayType = function(type){ * Check Flash can handle the source natively * * @param {Object} source The source object + * @param {Object} options The options passed to the tech * @return {String} 'probably', 'maybe', or '' (empty string) */ -Flash.nativeSourceHandler.canHandleSource = function(source){ +Flash.nativeSourceHandler.canHandleSource = function(source, options){ var type; function guessMimeType(src) { diff --git a/src/js/tech/html5.js b/src/js/tech/html5.js index aaf84346ec..56ebe06a0a 100644 --- a/src/js/tech/html5.js +++ b/src/js/tech/html5.js @@ -944,9 +944,10 @@ Html5.nativeSourceHandler.canPlayType = function(type){ * Check if the video element can handle the source natively * * @param {Object} source The source object + * @param {Object} options The options passed to the tech * @return {String} 'probably', 'maybe', or '' (empty string) */ -Html5.nativeSourceHandler.canHandleSource = function(source){ +Html5.nativeSourceHandler.canHandleSource = function(source, options){ var match, ext; // If a type was provided we should rely on that diff --git a/src/js/tech/tech.js b/src/js/tech/tech.js index 920192212e..98017020e3 100644 --- a/src/js/tech/tech.js +++ b/src/js/tech/tech.js @@ -726,16 +726,17 @@ Tech.withSourceHandlers = function(_Tech){ /* * Return the first source handler that supports the source * TODO: Answer question: should 'probably' be prioritized over 'maybe' - * @param {Object} source The source object + * @param {Object} source The source object + * @param {Object} options The options passed to the tech * @returns {Object} The first source handler that supports the source * @returns {null} Null if no source handler is found */ - _Tech.selectSourceHandler = function(source){ + _Tech.selectSourceHandler = function(source, options){ let handlers = _Tech.sourceHandlers || []; let can; for (let i = 0; i < handlers.length; i++) { - can = handlers[i].canHandleSource(source); + can = handlers[i].canHandleSource(source, options); if (can) { return handlers[i]; @@ -748,13 +749,14 @@ Tech.withSourceHandlers = function(_Tech){ /* * Check if the tech can support the given source * @param {Object} srcObj The source object + * @param {Object} options The options passed to the tech * @return {String} 'probably', 'maybe', or '' (empty string) */ - _Tech.canPlaySource = function(srcObj){ - let sh = _Tech.selectSourceHandler(srcObj); + _Tech.canPlaySource = function(srcObj, options){ + let sh = _Tech.selectSourceHandler(srcObj, options); if (sh) { - return sh.canHandleSource(srcObj); + return sh.canHandleSource(srcObj, options); } return ''; @@ -792,7 +794,7 @@ Tech.withSourceHandlers = function(_Tech){ * @return {Tech} self */ _Tech.prototype.setSource = function(source){ - let sh = _Tech.selectSourceHandler(source); + let sh = _Tech.selectSourceHandler(source, this.options_); if (!sh) { // Fall back to a native source hander when unsupported sources are diff --git a/test/unit/tech/flash.test.js b/test/unit/tech/flash.test.js index 722b9c490b..eadab9f93a 100644 --- a/test/unit/tech/flash.test.js +++ b/test/unit/tech/flash.test.js @@ -8,16 +8,16 @@ test('Flash.canPlaySource', function() { var canPlaySource = Flash.canPlaySource; // Supported - ok(canPlaySource({ type: 'video/mp4; codecs=avc1.42E01E,mp4a.40.2' }), 'codecs supported'); - ok(canPlaySource({ type: 'video/mp4' }), 'video/mp4 supported'); - ok(canPlaySource({ type: 'video/x-flv' }), 'video/x-flv supported'); - ok(canPlaySource({ type: 'video/flv' }), 'video/flv supported'); - ok(canPlaySource({ type: 'video/m4v' }), 'video/m4v supported'); - ok(canPlaySource({ type: 'VIDEO/FLV' }), 'capitalized mime type'); + ok(canPlaySource({ type: 'video/mp4; codecs=avc1.42E01E,mp4a.40.2' }, {}), 'codecs supported'); + ok(canPlaySource({ type: 'video/mp4' }, {}), 'video/mp4 supported'); + ok(canPlaySource({ type: 'video/x-flv' }, {}), 'video/x-flv supported'); + ok(canPlaySource({ type: 'video/flv' }, {}), 'video/flv supported'); + ok(canPlaySource({ type: 'video/m4v' }, {}), 'video/m4v supported'); + ok(canPlaySource({ type: 'VIDEO/FLV' }, {}), 'capitalized mime type'); // Not supported - ok(!canPlaySource({ type: 'video/webm; codecs="vp8, vorbis"' })); - ok(!canPlaySource({ type: 'video/webm' })); + ok(!canPlaySource({ type: 'video/webm; codecs="vp8, vorbis"' }, {})); + ok(!canPlaySource({ type: 'video/webm' }, {})); }); test('currentTime', function() { @@ -147,10 +147,10 @@ test('canPlayType should select the correct types to play', function () { test('canHandleSource should be able to work with src objects without a type', function () { let canHandleSource = Flash.nativeSourceHandler.canHandleSource; - equal('maybe', canHandleSource({ src: 'test.video.mp4' }), 'should guess that it is a mp4 video'); - equal('maybe', canHandleSource({ src: 'test.video.m4v' }), 'should guess that it is a m4v video'); - equal('maybe', canHandleSource({ src: 'test.video.flv' }), 'should guess that it is a flash video'); - equal('', canHandleSource({ src: 'test.video.wgg' }), 'should return empty string if it can not play the video'); + equal('maybe', canHandleSource({ src: 'test.video.mp4' }, {}), 'should guess that it is a mp4 video'); + equal('maybe', canHandleSource({ src: 'test.video.m4v' }, {}), 'should guess that it is a m4v video'); + equal('maybe', canHandleSource({ src: 'test.video.flv' }, {}), 'should guess that it is a flash video'); + equal('', canHandleSource({ src: 'test.video.wgg' }, {}), 'should return empty string if it can not play the video'); }); test('seekable', function() { diff --git a/test/unit/tech/html5.test.js b/test/unit/tech/html5.test.js index 4a8f254a59..92ac0fbc8a 100644 --- a/test/unit/tech/html5.test.js +++ b/test/unit/tech/html5.test.js @@ -190,16 +190,16 @@ test('native source handler canHandleSource', function(){ var canHandleSource = Html5.nativeSourceHandler.canHandleSource; - equal(canHandleSource({ type: 'video/mp4', src: 'video.flv' }), 'maybe', 'Native source handler reported type support'); - equal(canHandleSource({ src: 'http://www.example.com/video.mp4' }), 'maybe', 'Native source handler reported extension support'); - equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo&token=bar' }), 'maybe', 'Native source handler reported extension support'); - equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo' }), 'maybe', 'Native source handler reported extension support'); + equal(canHandleSource({ type: 'video/mp4', src: 'video.flv' }, {}), 'maybe', 'Native source handler reported type support'); + equal(canHandleSource({ src: 'http://www.example.com/video.mp4' }, {}), 'maybe', 'Native source handler reported extension support'); + equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo&token=bar' }, {}), 'maybe', 'Native source handler reported extension support'); + equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo' }, {}), 'maybe', 'Native source handler reported extension support'); // Test for issue videojs/video.js#1785 and other potential failures - equal(canHandleSource({ src: '' }), '', 'Native source handler handled empty src'); - equal(canHandleSource({}), '', 'Native source handler handled empty object'); - equal(canHandleSource({ src: 'foo' }), '', 'Native source handler handled bad src'); - equal(canHandleSource({ type: 'foo' }), '', 'Native source handler handled bad type'); + equal(canHandleSource({ src: '' }, {}), '', 'Native source handler handled empty src'); + equal(canHandleSource({}, {}), '', 'Native source handler handled empty object'); + equal(canHandleSource({ src: 'foo' }, {}), '', 'Native source handler handled bad src'); + equal(canHandleSource({ type: 'foo' }, {}), '', 'Native source handler handled bad type'); // Reset test video canPlayType Html5.TEST_VID.canPlayType = origCPT; diff --git a/test/unit/tech/tech.test.js b/test/unit/tech/tech.test.js index ef006a810f..ec0ea4a4a2 100644 --- a/test/unit/tech/tech.test.js +++ b/test/unit/tech/tech.test.js @@ -185,7 +185,8 @@ test('should add the source handler interface to a tech', function(){ } return ''; }, - canHandleSource: function(source){ + canHandleSource: function(source, options){ + strictEqual(tech.options_, options, 'the tech options were passed to the source handler canHandleSource'); if (source.type !=='no-support') { return 'probably'; } @@ -194,7 +195,7 @@ test('should add the source handler interface to a tech', function(){ handleSource: function(s, t, o){ strictEqual(tech, t, 'the tech instance was passed to the source handler'); strictEqual(sourceA, s, 'the tech instance was passed to the source handler'); - strictEqual(tech.options_, o, 'the tech options were passed to the source handler'); + strictEqual(tech.options_, o, 'the tech options were passed to the source handler handleSource'); return new handlerInternalState(); } }; @@ -203,7 +204,7 @@ test('should add the source handler interface to a tech', function(){ canPlayType: function(type){ return ''; // no support }, - canHandleSource: function(source){ + canHandleSource: function(source, options){ return ''; // no support }, handleSource: function(source, tech, options){ @@ -218,16 +219,16 @@ test('should add the source handler interface to a tech', function(){ strictEqual(MyTech.sourceHandlers[0], handlerTwo, 'handlerTwo was registered at the correct index (0)'); // Test handler selection - strictEqual(MyTech.selectSourceHandler(sourceA), handlerOne, 'handlerOne was selected to handle the valid source'); - strictEqual(MyTech.selectSourceHandler(sourceB), null, 'no handler was selected to handle the invalid source'); + strictEqual(MyTech.selectSourceHandler(sourceA, tech.options_), handlerOne, 'handlerOne was selected to handle the valid source'); + strictEqual(MyTech.selectSourceHandler(sourceB, tech.options_), null, 'no handler was selected to handle the invalid source'); // Test canPlayType return values strictEqual(MyTech.canPlayType(sourceA.type), 'probably', 'the Tech returned probably for the valid source'); strictEqual(MyTech.canPlayType(sourceB.type), '', 'the Tech returned an empty string for the invalid source'); // Test canPlaySource return values - strictEqual(MyTech.canPlaySource(sourceA), 'probably', 'the Tech returned probably for the valid source'); - strictEqual(MyTech.canPlaySource(sourceB), '', 'the Tech returned an empty string for the invalid source'); + strictEqual(MyTech.canPlaySource(sourceA, tech.options_), 'probably', 'the Tech returned probably for the valid source'); + strictEqual(MyTech.canPlaySource(sourceB, tech.options_), '', 'the Tech returned an empty string for the invalid source'); tech.addRemoteTextTrack({}); tech.addRemoteTextTrack({}); @@ -381,7 +382,7 @@ test('Tech#setSource clears currentSource_ after repeated loadstart', function() canPlayType: function(type) { return true; }, - canHandleSource: function(source) { + canHandleSource: function(source, options) { return true; }, handleSource: function(source, tech, options) {