Skip to content

Commit

Permalink
fix: gap jumping when gap exists at start position (#5384)
Browse files Browse the repository at this point in the history
Before playback starts the video element reports as seeking == true, but
because we haven't installed our seek listener yet, the gap controller
does not receive the seek event.

To work around this, we explicitly tell the gap controller when playback
starts so that it knows the startup position, and can synthesize a seek
event.
  • Loading branch information
baconz authored Jul 3, 2023
1 parent b1e7cc4 commit 6c71b0e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
19 changes: 17 additions & 2 deletions lib/media/gap_jumping_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ shaka.media.GapJumpingController = class {
/** @private {number} */
this.prevReadyState_ = video.readyState;

/** @private {number} */
this.startTime_ = 0;

/** @private {number} */
this.gapsJumped_ = 0;

Expand Down Expand Up @@ -123,6 +126,18 @@ shaka.media.GapJumpingController = class {
this.onPollGapJump_();
}

/**
* Called when playback has started and the video element is
* listening for seeks.
*
* @param {number} startTime
*/
onStarted(startTime) {
if (this.video_.seeking && !this.seekingEventReceived_) {
this.seekingEventReceived_ = true;
this.startTime_ = startTime;
}
}

/** Called when a seek has started. */
onSeeking() {
Expand Down Expand Up @@ -164,8 +179,8 @@ shaka.media.GapJumpingController = class {
// while paused on a livestream. We make an exception for time 0, since we
// may be _required_ to seek on startup before play can begin, but only if
// autoplay is enabled.
if (this.video_.paused && (this.video_.currentTime != 0 ||
(!this.video_.autoplay && this.video_.currentTime == 0))) {
if (this.video_.paused && (this.video_.currentTime != this.startTime_ ||
(!this.video_.autoplay && this.video_.currentTime == this.startTime_))) {
return;
}

Expand Down
11 changes: 11 additions & 0 deletions lib/media/playhead.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ shaka.media.MediaSourcePlayhead = class {
this.videoWrapper_ = new shaka.media.VideoWrapper(
mediaElement,
() => this.onSeeking_(),
(realStartTime) => this.onStarted_(realStartTime),
() => this.getStartTime_(startTime));

/** @type {shaka.util.Timer} */
Expand Down Expand Up @@ -390,6 +391,16 @@ shaka.media.MediaSourcePlayhead = class {
}
}

/**
* Called when the video element has started up and is listening for new seeks
*
* @param {number} startTime
* @private
*/
onStarted_(startTime) {
this.gapController_.onStarted(startTime);
}

/**
* Handles when a seek happens on the video.
*
Expand Down
7 changes: 6 additions & 1 deletion lib/media/video_wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@ shaka.media.VideoWrapper = class {
/**
* @param {!HTMLMediaElement} video
* @param {function()} onSeek Called when the video seeks.
* @param {function(number)} onStarted Called when the video has started.
* @param {function():number} getStartTime Calle to get the time to start at.
*/
constructor(video, onSeek, getStartTime) {
constructor(video, onSeek, onStarted, getStartTime) {
/** @private {HTMLMediaElement} */
this.video_ = video;

/** @private {function()} */
this.onSeek_ = onSeek;

/** @private {function(number)} */
this.onStarted_ = onStarted;

/** @private {?number} */
this.startTime_ = null;

Expand Down Expand Up @@ -173,6 +177,7 @@ shaka.media.VideoWrapper = class {
this.started_ = true;

this.eventManager_.listen(this.video_, 'seeking', () => this.onSeek_());
this.onStarted_(this.video_.currentTime);
}
};

Expand Down

0 comments on commit 6c71b0e

Please sign in to comment.