Skip to content

Commit

Permalink
Ensure seeks are not ignored in ended state.
Browse files Browse the repository at this point in the history
We should only ignore seek to the current position if we are
currently READY or BUFFERING. Also, pending initial seek positions
should only be saved while we have an empty timeline, independent of
the player state.

Issue:#6886
PiperOrigin-RevId: 297813854
  • Loading branch information
tonihei authored and ojw28 committed Feb 28, 2020
1 parent 68c401b commit 6c7a2c3
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -902,12 +902,14 @@ private void seekToInternal(SeekPosition seekPosition) throws ExoPlaybackExcepti
}

try {
if (playbackInfo.timeline.isEmpty() || !playlist.isPrepared()) {
if (playbackInfo.timeline.isEmpty()) {
// Save seek position for later, as we are still waiting for a prepared source.
pendingInitialSeekPosition = seekPosition;
} else if (resolvedSeekPosition == null) {
// End playback, as we didn't manage to find a valid seek position.
setState(Player.STATE_ENDED);
if (playbackInfo.playbackState != Player.STATE_IDLE) {
setState(Player.STATE_ENDED);
}
resetInternal(
/* resetRenderers= */ false,
/* resetPosition= */ true,
Expand All @@ -926,7 +928,9 @@ private void seekToInternal(SeekPosition seekPosition) throws ExoPlaybackExcepti
playingPeriodHolder.mediaPeriod.getAdjustedSeekPositionUs(
newPeriodPositionUs, seekParameters);
}
if (C.usToMs(newPeriodPositionUs) == C.usToMs(playbackInfo.positionUs)) {
if (C.usToMs(newPeriodPositionUs) == C.usToMs(playbackInfo.positionUs)
&& (playbackInfo.playbackState == Player.STATE_BUFFERING
|| playbackInfo.playbackState == Player.STATE_READY)) {
// Seek will be performed to the current position. Do nothing.
periodPositionUs = playbackInfo.positionUs;
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5728,6 +5728,43 @@ public void onPlayerError(
assertThat(trackSelectionsAfterError.get().get(1)).isNotNull(); // Audio renderer.
}

@Test
public void seekToCurrentPosition_inEndedState_switchesToBufferingStateAndContinuesPlayback()
throws Exception {
MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount = */ 1));
AtomicInteger windowIndexAfterFinalEndedState = new AtomicInteger();
ActionSchedule actionSchedule =
new ActionSchedule.Builder("seekToCurrentPosition_inEndedState")
.waitForPlaybackState(Player.STATE_ENDED)
.addMediaSources(mediaSource)
.executeRunnable(
new PlayerRunnable() {
@Override
public void run(SimpleExoPlayer player) {
player.seekTo(player.getCurrentPosition());
}
})
.waitForPlaybackState(Player.STATE_READY)
.waitForPlaybackState(Player.STATE_ENDED)
.executeRunnable(
new PlayerRunnable() {
@Override
public void run(SimpleExoPlayer player) {
windowIndexAfterFinalEndedState.set(player.getCurrentWindowIndex());
}
})
.build();
new Builder()
.setMediaSources(mediaSource)
.setActionSchedule(actionSchedule)
.build(context)
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);

assertThat(windowIndexAfterFinalEndedState.get()).isEqualTo(1);
}

// Internal methods.

private static ActionSchedule.Builder addSurfaceSwitch(ActionSchedule.Builder builder) {
Expand Down

0 comments on commit 6c7a2c3

Please sign in to comment.