Refs #16 Fix video does not resume playing after quality change

When the HTML5 preload attribute is set to 'none' or when using Safari (even when the
preload attribute is not 'none'), the video does not resume playing after the quality is
changed using the quality selector menu. The quality selector plugin was listening for the
'loadeddata' event in order to know when to resume playback, but the 'loadeddata' event
does not fire when the preload attribute is set to 'none', and Safari does not fetch
enough data to emit a 'loadeddata' event.
This commit is contained in:
Matt Luedke 2018-01-08 15:07:32 -05:00
parent 1f1f78b267
commit 8feeafbf00
4 changed files with 112 additions and 7 deletions

View file

@ -3,7 +3,8 @@
var _ = require('underscore'),
events = require('./events'),
qualitySelectorFactory = require('./components/QualitySelector'),
sourceInterceptorFactory = require('./middleware/SourceInterceptor');
sourceInterceptorFactory = require('./middleware/SourceInterceptor'),
SafeSeek = require('./util/SafeSeek');
module.exports = function(videojs) {
videojs = videojs || window.videojs;
@ -12,8 +13,7 @@ module.exports = function(videojs) {
sourceInterceptorFactory(videojs);
videojs.hook('setup', function(player) {
// Add handler to switch sources when the user requests a change
player.on(events.QUALITY_REQUESTED, function(event, newSource) {
function changeQuality(event, newSource) {
var sources = player.currentSources(),
currentTime = player.currentTime(),
isPaused = player.paused(),
@ -29,15 +29,36 @@ module.exports = function(videojs) {
// following updates the original object in `sources`.
selectedSource.selected = true;
if (player._qualitySelectorSafeSeek) {
player._qualitySelectorSafeSeek.onQualitySelectionChange();
}
player.src(sources);
player.one('loadeddata', function() {
player.currentTime(currentTime);
player.ready(function() {
if (!player._qualitySelectorSafeSeek || player._qualitySelectorSafeSeek.hasFinished()) {
// Either we don't have a pending seek action or the one that we have is no
// longer applicable. This block must be within a `player.ready` callback
// because the call to `player.src` above is asynchronous, and so not
// having it within this `ready` callback would cause the SourceInterceptor
// to execute after this block instead of before.
//
// We save the `currentTime` within the SafeSeek instance because if
// multiple QUALITY_REQUESTED events are received before the SafeSeek
// operation finishes, the player's `currentTime` will be `0` if the
// player's `src` is updated but the player's `currentTime` has not yet
// been set by the SafeSeek operation.
player._qualitySelectorSafeSeek = new SafeSeek(player, currentTime);
}
if (!isPaused) {
player.play();
}
});
});
}
// Add handler to switch sources when the user requests a change
player.on(events.QUALITY_REQUESTED, changeQuality);
});
};