diff --git a/CHANGELOG.md b/CHANGELOG.md index a44f07262c..9f38dddad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ CHANGELOG ========= ## HEAD (Unreleased) -_(none)_ +* @imbcmdth updated currentSrc to return src instead of blob urls in html5 tech. Fixes #2232 ([view](https://github.com/videojs/video.js/pull/2232)) -------------------- diff --git a/src/js/media/html5.js b/src/js/media/html5.js index f87d186283..5f86f8c9bc 100644 --- a/src/js/media/html5.js +++ b/src/js/media/html5.js @@ -329,7 +329,13 @@ vjs.Html5.prototype.setSrc = function(src) { }; vjs.Html5.prototype.load = function(){ this.el_.load(); }; -vjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; }; +vjs.Html5.prototype.currentSrc = function(){ + if (this.currentSource_) { + return this.currentSource_.src; + } else { + return this.el_.currentSrc; + } +}; vjs.Html5.prototype.poster = function(){ return this.el_.poster; }; vjs.Html5.prototype.setPoster = function(val){ this.el_.poster = val; }; diff --git a/src/js/media/media.js b/src/js/media/media.js index 0a7cd59ad5..3c6f7588c7 100644 --- a/src/js/media/media.js +++ b/src/js/media/media.js @@ -510,7 +510,14 @@ vjs.MediaTechController.withSourceHandlers = function(Tech){ this.disposeSourceHandler(); this.off('dispose', this.disposeSourceHandler); - this.currentSource_ = source; + // Set currentSource_ asynchronously to simulate the media element's + // asynchronous execution of the `resource selection algorithm` + this.setTimeout(vjs.bind(this, function () { + if (source && source.src !== '') { + this.currentSource_ = source; + } + }), 0); + this.sourceHandler_ = sh.handleSource(source, this); this.on('dispose', this.disposeSourceHandler); diff --git a/test/unit/media.js b/test/unit/media.js index bdf1da641a..fd22119d22 100644 --- a/test/unit/media.js +++ b/test/unit/media.js @@ -221,6 +221,10 @@ test('should add the source hanlder interface to a tech', function(){ // Pass a source through the source handler process of a tech instance tech.setSource(sourceA); + + // Increment clock since currentSource_ is set asynchronously + this.clock.tick(1); + strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored'); ok(tech.sourceHandler_.dispose, 'the handlerOne state instance was stored'); @@ -250,4 +254,54 @@ test('should handle unsupported sources with the source hanlder API', function() tech.setSource(''); ok(usedNative, 'native source handler was used when an unsupported source was set'); -}); \ No newline at end of file +}); + +test('should emulate the video element\'s behavior for currentSrc when src is set', function(){ + var mockPlayer = { + off: this.noop, + trigger: this.noop + }; + var sourceA = { src: 'foo.mp4', type: 'video/mp4' }; + var sourceB = { src: '', type: 'video/mp4' }; + + // Define a new tech class + var Tech = videojs.MediaTechController.extend(); + + // Extend Tech with source handlers + vjs.MediaTechController.withSourceHandlers(Tech); + + // Create an instance of Tech + var tech = new Tech(mockPlayer); + + // Create source handlers + var handler = { + canHandleSource: function(source){ + return 'probably'; + }, + handleSource: function(s, t){return {};} + }; + + Tech.registerSourceHandler(handler); + + // Pass a source through the source handler process of a tech instance + tech.setSource(sourceA); + + // Test that currentSource_ is not immediately specified + strictEqual(tech.currentSource_, undefined, 'sourceA was not stored immediately'); + + this.clock.tick(1); + + // Test that currentSource_ is specified after yielding to the event loop + strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored'); + + // Pass a source with an empty src + tech.setSource(sourceB); + + // Test that currentSource_ is not immediately changed + strictEqual(tech.currentSource_, sourceA, 'sourceB was not stored immediately'); + + this.clock.tick(1); + + // Test that currentSource_ is still unchanged + strictEqual(tech.currentSource_, sourceA, 'sourceB was not stored if equal to the empty string'); +});