diff --git a/CONTRIBUTORS b/CONTRIBUTORS index bd3b9c551c..45c66f30b7 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -24,6 +24,7 @@ Andy Hochhaus Chad Assareh +Chris Fillmore Costel Madalin Grecu Donato Borrello Esteban Dosztal diff --git a/lib/player.js b/lib/player.js index 8c40b76b6b..17d4c55e73 100644 --- a/lib/player.js +++ b/lib/player.js @@ -88,6 +88,9 @@ shaka.Player = function(video, opt_dependencyInjector) { /** @private {Promise} */ this.mediaSourceOpen_ = null; + /** @private {Promise} */ + this.unloadPromise_ = null; + /** @private {shaka.media.Playhead} */ this.playhead_ = null; @@ -378,14 +381,14 @@ shaka.Player.probeSupport = function() { */ shaka.Player.prototype.load = function(manifestUri, opt_startTime, opt_manifestParserFactory) { - var unloadPromise = this.unload(); + this.unload(); var loadChain = new shaka.util.CancelableChain(); this.loadChain_ = loadChain; this.dispatchEvent(new shaka.util.FakeEvent('loading')); return loadChain.then(function() { - return unloadPromise; - }).then(function() { + return this.unloadPromise_; + }.bind(this)).then(function() { goog.asserts.assert(this.networkingEngine_, 'Must not be destroyed'); return shaka.media.ManifestParser.getFactory( @@ -753,7 +756,16 @@ shaka.Player.prototype.isBuffering = function() { * @export */ shaka.Player.prototype.unload = function() { - if (this.destroyed_) return Promise.resolve(); + if (this.unloadPromise_) { + // An unload is currently in progress. Do not initiate another one. + return this.unloadPromise_; + } + + if (this.destroyed_) { + // No unloading necessary. + return Promise.resolve(); + } + this.dispatchEvent(new shaka.util.FakeEvent('unloading')); if (this.loadChain_) { @@ -761,16 +773,32 @@ shaka.Player.prototype.unload = function() { var interrupt = new shaka.util.Error( shaka.util.Error.Category.PLAYER, shaka.util.Error.Code.LOAD_INTERRUPTED); - return this.loadChain_.cancel(interrupt) - .then(this.resetStreaming_.bind(this)); + return this.createUnloadPromise_(this.loadChain_.cancel(interrupt) + .then(this.resetStreaming_.bind(this))); } else { - // No loads or unloads are in progress. - // Just reset the streaming system if needed. - return this.resetStreaming_(); + // No loads are in progress. Just reset the streaming system if needed. + return this.createUnloadPromise_(this.resetStreaming_()); } }; +/** + * Create an unload promise and store it on the player until unloading + * is complete. + * @private + * @param {!Promise} unloadProcess Unloading steps to perform before destroying + * the unload promise. + * @return {!Promise} + */ +shaka.Player.prototype.createUnloadPromise_ = function(unloadProcess) { + this.unloadPromise_ = unloadProcess.then(function() { + this.unloadPromise_ = null; + }.bind(this)); + + return this.unloadPromise_; +}; + + /** * Gets the current effective playback rate. If using trick play, it will * return the current trick play rate; otherwise, it will return the video