From 0edecaf856fd6a3465a27031a8587ef1a4bb7276 Mon Sep 17 00:00:00 2001 From: jrivera Date: Thu, 11 Jun 2015 20:29:04 -0400 Subject: [PATCH 1/4] Ensure that currentSrc is set before any other loadstart handlers have had a chance to execute --- src/js/media/media.js | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/js/media/media.js b/src/js/media/media.js index 3c6f7588c7..b82ebb79f4 100644 --- a/src/js/media/media.js +++ b/src/js/media/media.js @@ -36,6 +36,8 @@ vjs.MediaTechController = vjs.Component.extend({ this.emulateTextTracks(); } + this.on('loadstart', this.updateCurrentSource); + this.initTextTrackListeners(); } }); @@ -168,6 +170,24 @@ vjs.MediaTechController.prototype.onTap = function(){ this.player().userActive(!this.player().userActive()); }; +/** + * Set currentSource_ asynchronously to simulate the media element's + * asynchronous execution of the `resource selection algorithm` + * + * currentSource_ is set either as the first loadstart event OR + * in a timeout to make sure it is set asynchronously before anything else + * but before other loadstart handlers have had a chance to execute + */ +vjs.MediaTechController.prototype.updateCurrentSource = function () { + // We could have been called with a 0-ms setTimeout OR via loadstart (which ever + // happens first) so we should clear the timeout to be a good citizen + this.clearTimeout(this.updateSourceTimer_); + + if (this.pendingSource_) { + this.currentSource_ = this.pendingSource_; + } +}; + /* Fallbacks for unsupported event types ================================================================================ */ // Manually trigger progress events based on changes to the buffered amount @@ -510,13 +530,11 @@ vjs.MediaTechController.withSourceHandlers = function(Tech){ this.disposeSourceHandler(); this.off('dispose', this.disposeSourceHandler); - // 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); + // Schedule currentSource_ to be set asynchronously + if (source && source.src !== '') { + this.pendingSource_ = source; + this.updateSourceTimer_ = this.setTimeout(vjs.bind(this, this.updateCurrentSource), 0); + } this.sourceHandler_ = sh.handleSource(source, this); this.on('dispose', this.disposeSourceHandler); From 871cc01dad921bb93a0db2461a81354e97e1d9a0 Mon Sep 17 00:00:00 2001 From: jrivera Date: Thu, 11 Jun 2015 20:29:23 -0400 Subject: [PATCH 2/4] Allow Techs to return an empty string for currentSrc without deferring to src --- src/js/media/media.js | 2 ++ src/js/player.js | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/js/media/media.js b/src/js/media/media.js index b82ebb79f4..6a98fa84fa 100644 --- a/src/js/media/media.js +++ b/src/js/media/media.js @@ -446,6 +446,8 @@ vjs.MediaTechController.prototype['featuresNativeTextTracks'] = false; * */ vjs.MediaTechController.withSourceHandlers = function(Tech){ + Tech.prototype.currentSource_ = {src: ''}; + /** * Register a source handler * Source handlers are scripts for handling specific formats. diff --git a/src/js/player.js b/src/js/player.js index 899de475d9..8d919f6a3c 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -1228,7 +1228,12 @@ vjs.Player.prototype.load = function(){ * @return {String} The current source */ vjs.Player.prototype.currentSrc = function(){ - return this.techGet('currentSrc') || this.cache_.src || ''; + var techSrc = this.techGet('currentSrc'); + + if (techSrc === undefined) { + return this.cache_.src || ''; + } + return techSrc; }; /** From a93447b3d6f3eb6918ac1555f7501928286aa899 Mon Sep 17 00:00:00 2001 From: jrivera Date: Thu, 11 Jun 2015 20:53:35 -0400 Subject: [PATCH 3/4] Fixed failing assertion --- test/unit/media.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/media.js b/test/unit/media.js index fd22119d22..054976a180 100644 --- a/test/unit/media.js +++ b/test/unit/media.js @@ -287,7 +287,7 @@ test('should emulate the video element\'s behavior for currentSrc when src is se tech.setSource(sourceA); // Test that currentSource_ is not immediately specified - strictEqual(tech.currentSource_, undefined, 'sourceA was not stored immediately'); + deepEqual(tech.currentSource_, {src:''}, 'sourceA was not stored immediately'); this.clock.tick(1); From 4ab4e7805773cc5049bf3c48507b03f41a532564 Mon Sep 17 00:00:00 2001 From: jrivera Date: Mon, 15 Jun 2015 16:19:30 -0400 Subject: [PATCH 4/4] Added underscore to new internal function `updateCurrentSource` --- src/js/media/media.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/media/media.js b/src/js/media/media.js index 6a98fa84fa..67dca61703 100644 --- a/src/js/media/media.js +++ b/src/js/media/media.js @@ -36,7 +36,7 @@ vjs.MediaTechController = vjs.Component.extend({ this.emulateTextTracks(); } - this.on('loadstart', this.updateCurrentSource); + this.on('loadstart', this.updateCurrentSource_); this.initTextTrackListeners(); } @@ -178,7 +178,7 @@ vjs.MediaTechController.prototype.onTap = function(){ * in a timeout to make sure it is set asynchronously before anything else * but before other loadstart handlers have had a chance to execute */ -vjs.MediaTechController.prototype.updateCurrentSource = function () { +vjs.MediaTechController.prototype.updateCurrentSource_ = function () { // We could have been called with a 0-ms setTimeout OR via loadstart (which ever // happens first) so we should clear the timeout to be a good citizen this.clearTimeout(this.updateSourceTimer_); @@ -535,7 +535,7 @@ vjs.MediaTechController.withSourceHandlers = function(Tech){ // Schedule currentSource_ to be set asynchronously if (source && source.src !== '') { this.pendingSource_ = source; - this.updateSourceTimer_ = this.setTimeout(vjs.bind(this, this.updateCurrentSource), 0); + this.updateSourceTimer_ = this.setTimeout(vjs.bind(this, this.updateCurrentSource_), 0); } this.sourceHandler_ = sh.handleSource(source, this);