Skip to content

Commit

Permalink
fix: Disable seek retry cooldown on most platforms (#7010)
Browse files Browse the repository at this point in the history
Previously, we added a 1 second "cooldown" period between attempts to
perform a corrective seek.
This was for the benefit of old v1 Chromecasts, which found the process
of seeking so slow that they would sometimes get stuck in an infinite
loop trying to start a presentation.
However, that cooldown period was causing issues in some situations
during seeking, so this PR removes the restriction on everything but
pre-Android Chromecast devices.

Fixes #4393
Fixes #5202

---------

Co-authored-by: Álvaro Velad Galván <[email protected]>
  • Loading branch information
theodab and avelad authored Jul 9, 2024
1 parent dc34ec4 commit dcc60f9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
21 changes: 15 additions & 6 deletions lib/media/playhead.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ goog.require('shaka.media.VideoWrapper');
goog.require('shaka.util.EventManager');
goog.require('shaka.util.IReleasable');
goog.require('shaka.util.MediaReadyState');
goog.require('shaka.util.Platform');
goog.require('shaka.util.Timer');
goog.requireType('shaka.media.PresentationTimeline');

Expand Down Expand Up @@ -420,12 +421,20 @@ shaka.media.MediaSourcePlayhead = class {

const gapLimit = shaka.media.GapJumpingController.BROWSER_GAP_TOLERANCE;
if (Math.abs(targetTime - currentTime) > gapLimit) {
// You can only seek like this every so often. This is to prevent an
// infinite loop on systems where changing currentTime takes a significant
// amount of time (e.g. Chromecast).
const time = Date.now() / 1000;
if (!this.lastCorrectiveSeek_ || this.lastCorrectiveSeek_ < time - 1) {
this.lastCorrectiveSeek_ = time;
let canCorrectiveSeek = false;
if (shaka.util.Platform.isSeekingSlow()) {
// You can only seek like this every so often. This is to prevent an
// infinite loop on systems where changing currentTime takes a
// significant amount of time (e.g. Chromecast).
const time = Date.now() / 1000;
if (!this.lastCorrectiveSeek_ || this.lastCorrectiveSeek_ < time - 1) {
this.lastCorrectiveSeek_ = time;
canCorrectiveSeek = true;
}
} else {
canCorrectiveSeek = true;
}
if (canCorrectiveSeek) {
this.videoWrapper_.setTime(targetTime);
return;
}
Expand Down
19 changes: 19 additions & 0 deletions lib/util/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,25 @@ shaka.util.Platform = class {
return true;
}

/**
* On some platforms, such as v1 Chromecasts, the act of seeking can take a
* significant amount of time.
*
* @return {boolean}
*/
static isSeekingSlow() {
const Platform = shaka.util.Platform;
if (Platform.isChromecast()) {
if (Platform.isAndroidCastDevice()) {
// Android-based Chromecasts are new enough to not be a problem.
return false;
} else {
return true;
}
}
return false;
}

/**
* Returns true if MediaKeys is polyfilled
*
Expand Down
5 changes: 4 additions & 1 deletion test/media/playhead_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,10 @@ describe('Playhead', () => {
expect(onSeek).toHaveBeenCalled();
}); // clamps playhead after seeking for VOD

it('doesn\'t repeatedly re-seek', () => {
it('doesn\'t repeatedly re-seek in seeking slow platforms', () => {
if (!shaka.util.Platform.isSeekingSlow()) {
pending('No seeking slow platform');
}
video.readyState = HTMLMediaElement.HAVE_METADATA;

video.buffered = createFakeBuffered([{start: 25, end: 55}]);
Expand Down

0 comments on commit dcc60f9

Please sign in to comment.