Browse Source

Seek to seekable start when before the seekable window (#1260)

pull/6/head
Joe Forbes 8 years ago
committed by GitHub
parent
commit
7fb8820a23
  1. 42
      src/playback-watcher.js
  2. 56
      test/playback-watcher.test.js

42
src/playback-watcher.js

@ -154,18 +154,32 @@ export default class PlaybackWatcher {
* @private
*/
fixesBadSeeks_() {
let seekable = this.seekable();
let currentTime = this.tech_.currentTime();
const seeking = this.tech_.seeking();
const seekable = this.seekable();
const currentTime = this.tech_.currentTime();
let seekTo;
if (this.tech_.seeking() &&
this.outsideOfSeekableWindow_(seekable, currentTime)) {
let seekableEnd = seekable.end(seekable.length - 1);
if (seeking && this.afterSeekableWindow_(seekable, currentTime)) {
const seekableEnd = seekable.end(seekable.length - 1);
// sync to live point (if VOD, our seekable was updated and we're simply adjusting)
seekTo = seekableEnd;
}
if (seeking && this.beforeSeekableWindow_(seekable, currentTime)) {
const seekableStart = seekable.start(0);
// sync to the beginning of the live window
// provide a buffer of .1 seconds to handle rounding/imprecise numbers
seekTo = seekableStart + 0.1;
}
if (typeof seekTo !== 'undefined') {
this.logger_(`Trying to seek outside of seekable at time ${currentTime} with ` +
`seekable range ${Ranges.printableRange(seekable)}. Seeking to ` +
`${seekableEnd}.`);
this.tech_.setCurrentTime(seekableEnd);
`seekable range ${Ranges.printableRange(seekable)}. Seeking to ` +
`${seekTo}.`);
this.tech_.setCurrentTime(seekTo);
return true;
}
@ -231,7 +245,7 @@ export default class PlaybackWatcher {
return true;
}
if (this.fellOutOfLiveWindow_(seekable, currentTime)) {
if (this.beforeSeekableWindow_(seekable, currentTime)) {
let livePoint = seekable.end(seekable.length - 1);
this.logger_(`Fell out of live window at time ${currentTime}. Seeking to ` +
@ -278,26 +292,26 @@ export default class PlaybackWatcher {
return false;
}
outsideOfSeekableWindow_(seekable, currentTime) {
afterSeekableWindow_(seekable, currentTime) {
if (!seekable.length) {
// we can't make a solid case if there's no seekable, default to false
return false;
}
// provide a buffer of .1 seconds to handle rounding/imprecise numbers
if (currentTime < seekable.start(0) - 0.1 ||
currentTime > seekable.end(seekable.length - 1) + 0.1) {
if (currentTime > seekable.end(seekable.length - 1) + 0.1) {
return true;
}
return false;
}
fellOutOfLiveWindow_(seekable, currentTime) {
beforeSeekableWindow_(seekable, currentTime) {
if (seekable.length &&
// can't fall before 0 and 0 seekable start identifies VOD stream
seekable.start(0) > 0 &&
currentTime < seekable.start(0)) {
// provide a buffer of .1 seconds to handle rounding/imprecise numbers
currentTime < seekable.start(0) - 0.1) {
return true;
}

56
test/playback-watcher.test.js

@ -458,14 +458,14 @@ QUnit.test('fixes bad seeks', function(assert) {
currentTime = 0;
assert.ok(playbackWatcher.fixesBadSeeks_(), 'acts when seek before seekable range');
assert.equal(seeks.length, 2, 'seeked');
assert.equal(seeks[1], 45, 'player seeked to live point');
assert.equal(seeks[1], 1.1, 'player seeked to start of the live window');
currentTime = 30;
assert.ok(!playbackWatcher.fixesBadSeeks_(), 'does nothing when time within range');
assert.equal(seeks.length, 2, 'did not seek');
});
QUnit.test('seeks to live point if we try to seek outside of seekable', function(assert) {
QUnit.test('corrects seek outside of seekable', function(assert) {
// set an arbitrary live source
this.player.src({
src: 'liveStart30sBefore.m3u8',
@ -512,7 +512,7 @@ QUnit.test('seeks to live point if we try to seek outside of seekable', function
currentTime = 0;
this.player.tech_.trigger('waiting');
assert.equal(seeks.length, 2, 'seeked');
assert.equal(seeks[1], 45, 'player seeked to live point');
assert.equal(seeks[1], 1.1, 'player seeked to start of the live window');
// inside of seekable range
currentTime = 10;
@ -538,7 +538,7 @@ QUnit.test('seeks to live point if we try to seek outside of seekable', function
currentTime = 0;
playbackWatcher.checkCurrentTime_();
assert.equal(seeks.length, 4, 'seeked');
assert.equal(seeks[3], 45, 'player seeked to live point');
assert.equal(seeks[3], 1.1, 'player seeked to live point');
currentTime = 10;
playbackWatcher.checkCurrentTime_();
@ -651,66 +651,66 @@ QUnit.test('skips gap from video underflow', function(assert) {
});
QUnit.test('detects live window falloff', function(assert) {
let fellOutOfLiveWindow_ =
this.playbackWatcher.fellOutOfLiveWindow_.bind(this.playbackWatcher);
let beforeSeekableWindow_ =
this.playbackWatcher.beforeSeekableWindow_.bind(this.playbackWatcher);
assert.ok(
fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 10),
beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 10),
'true if playlist live and current time before seekable');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([]), 10),
!beforeSeekableWindow_(videojs.createTimeRanges([]), 10),
'false if no seekable range');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([[0, 10]]), -1),
!beforeSeekableWindow_(videojs.createTimeRanges([[0, 10]]), -1),
'false if seekable range starts at 0');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 11),
!beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 11),
'false if current time at seekable start');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 20),
!beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 20),
'false if current time at seekable end');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 15),
!beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 15),
'false if current time within seekable range');
assert.ok(
!fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 21),
!beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 21),
'false if current time past seekable range');
assert.ok(
fellOutOfLiveWindow_(videojs.createTimeRanges([[11, 20]]), 0),
beforeSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 0),
'true if current time is 0 and earlier than seekable range');
});
QUnit.test('detects outside of seekable window', function(assert) {
let outsideOfSeekableWindow =
this.playbackWatcher.outsideOfSeekableWindow_.bind(this.playbackWatcher);
QUnit.test('detects beyond seekable window', function(assert) {
let afterSeekableWindow_ =
this.playbackWatcher.afterSeekableWindow_.bind(this.playbackWatcher);
assert.ok(
outsideOfSeekableWindow(videojs.createTimeRanges([[11, 20]]), 10.8),
'true if before seekable range');
!afterSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 10.8),
'false if before seekable range');
assert.ok(
outsideOfSeekableWindow(videojs.createTimeRanges([[11, 20]]), 20.2),
afterSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 20.2),
'true if after seekable range');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges([[11, 20]]), 10.9),
!afterSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 10.9),
'false if within starting seekable range buffer');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges([[11, 20]]), 20.1),
!afterSeekableWindow_(videojs.createTimeRanges([[11, 20]]), 20.1),
'false if within ending seekable range buffer');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges(), 10),
!afterSeekableWindow_(videojs.createTimeRanges(), 10),
'false if no seekable range');
assert.ok(
outsideOfSeekableWindow(videojs.createTimeRanges([[0, 10]]), -0.2),
'true even if current time is negative');
!afterSeekableWindow_(videojs.createTimeRanges([[0, 10]]), -0.2),
'false if current time is negative');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges([[0, 10]]), 5),
!afterSeekableWindow_(videojs.createTimeRanges([[0, 10]]), 5),
'false if within seekable range');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges([[0, 10]]), 0),
!afterSeekableWindow_(videojs.createTimeRanges([[0, 10]]), 0),
'false if within seekable range');
assert.ok(
!outsideOfSeekableWindow(videojs.createTimeRanges([[0, 10]]), 10),
!afterSeekableWindow_(videojs.createTimeRanges([[0, 10]]), 10),
'false if within seekable range');
});
Loading…
Cancel
Save