554cfb19 by David LaPalomento

Seek to a safe position when resuming live playlists

If the player has fallen out of the live window, seek back to the earliest safe position when playback resumes. If the player is paused too far ahead of the live point, seek back to the latest safe position when resuming.
1 parent 0227bf64
......@@ -321,12 +321,21 @@ videojs.Hls.prototype.play = function() {
this.mediaIndex = 0;
}
// seek to the latest safe point in the media timeline when first
// playing live streams
if (this.duration() === Infinity &&
this.playlists.media() &&
!this.player().hasClass('vjs-has-started')) {
// we may need to seek to begin playing safely for live playlists
if (this.duration() === Infinity) {
// if this is the first time we're playing the stream or we're
// ahead of the latest safe playback position, seek to the live
// point
if (!this.player().hasClass('vjs-has-started') ||
this.currentTime() > this.seekable().end(0)) {
this.setCurrentTime(this.seekable().end(0));
} else if (this.currentTime() < this.seekable().start(0)) {
// if the viewer has paused and we fell out of the live window,
// seek forward to the earliest available position
this.setCurrentTime(this.seekable().start(0));
}
}
// delegate back to the Flash implementation
......
......@@ -1686,6 +1686,51 @@ test('live playlist starts with correct currentTime value', function() {
'currentTime is updated at playback');
});
test('resets the time to a seekable position when resuming a live stream ' +
'after a long break', function() {
var seekTarget;
player.src({
src: 'live0.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
requests.shift().respond(200, null,
'#EXTM3U\n' +
'#EXT-X-MEDIA-SEQUENCE:16\n' +
'#EXTINF:10,\n' +
'16.ts\n');
// mock out the player to simulate a live stream that has been
// playing for awhile
player.addClass('vjs-has-started');
player.hls.seekable = function() {
return {
start: function() {
return 160;
},
end: function() {
return 170;
}
};
};
player.hls.currentTime = function() {
return 0;
};
player.hls.setCurrentTime = function(time) {
if (time !== undefined) {
seekTarget = time;
}
};
player.play();
equal(seekTarget, player.seekable().start(0), 'seeked to the start of seekable');
player.hls.currentTime = function() {
return 180;
};
player.play();
equal(seekTarget, player.seekable().end(0), 'seeked to the end of seekable');
});
test('mediaIndex is zero before the first segment loads', function() {
window.manifests['first-seg-load'] =
'#EXTM3U\n' +
......