Add seekToNext method to Player

PiperOrigin-RevId: 383816880
This commit is contained in:
kimvde 2021-07-09 12:02:11 +01:00 committed by Oliver Woodman
parent 7e6d82237a
commit 699579fd4e
5 changed files with 84 additions and 6 deletions

View File

@ -6,12 +6,11 @@
* Add `needsReconfiguration` API to the `MediaCodecAdapter` interface.
* Add `getSeekForwardIncrement`, `seekForward`, `getSeekBackIncrement`
and `seekBack` methods to `Player`.
* Add `getMaxSeekToPreviousPosition` and `seekToPrevious` methods to
`Player`.
* Add `seekForward` and `seekBack` methods to `Player`.
* Add `getMaxSeekToPreviousPosition`, `seekToPrevious` and `seekToNext`
methods to `Player`.
* Rename `Player` commands `COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM`,
`COMMAND_SEEK_TO_NEXT_MEDIA_ITEM`, `COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM` and
`COMMAND_SEEK_TO_MEDIA_ITEM` to `COMMAND_SEEK_IN_CURRENT_WINDOW`,
`COMMAND_SEEK_TO_NEXT_MEDIA_ITEM`, `COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM`
and `COMMAND_SEEK_TO_MEDIA_ITEM` to `COMMAND_SEEK_IN_CURRENT_WINDOW`,
`COMMAND_SEEK_TO_NEXT_WINDOW`, `COMMAND_SEEK_TO_PREVIOUS_WINDOW` and
`COMMAND_SEEK_TO_WINDOW`, respectively.
* Make `Player` depend on the new `PlaybackException` class instead of

View File

@ -175,6 +175,19 @@ public abstract class BasePlayer implements Player {
}
}
@Override
public final void seekToNext() {
Timeline timeline = getCurrentTimeline();
if (timeline.isEmpty() || isPlayingAd()) {
return;
}
if (hasNext()) {
next();
} else if (isCurrentWindowLive() && isCurrentWindowDynamic()) {
seekToDefaultPosition();
}
}
@Override
public final void setPlaybackSpeed(float speed) {
setPlaybackParameters(getPlaybackParameters().withSpeed(speed));

View File

@ -297,6 +297,11 @@ public class ForwardingPlayer implements Player {
player.next();
}
@Override
public void seekToNext() {
player.seekToNext();
}
@Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
player.setPlaybackParameters(playbackParameters);

View File

@ -1715,6 +1715,20 @@ public interface Player {
*/
void next();
/**
* Seeks to a later position in the current or next window (if available). More precisely:
*
* <ul>
* <li>If the timeline is empty or seeking is not possible, does nothing.
* <li>Otherwise, if {@link #hasNext() a next window exists}, seeks to the default position of
* the next window.
* <li>Otherwise, if the current window is {@link #isCurrentWindowLive() live} and has not
* ended, seeks to the live edge of the current window.
* <li>Otherwise, does nothing.
* </ul>
*/
void seekToNext();
/**
* Attempts to set the playback parameters. Passing {@link PlaybackParameters#DEFAULT} resets the
* player to the default, which means there is no speed or pitch adjustment.

View File

@ -10511,7 +10511,7 @@ public final class ExoPlayerTest {
}
@Test
public void seekToPrevious_closeToStart_seeksToPreviousWindow() {
public void seekToPrevious_withPreviousWindowAndCloseToStart_seeksToPreviousWindow() {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource()));
player.seekTo(/* windowIndex= */ 1, C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS);
@ -10520,6 +10520,8 @@ public final class ExoPlayerTest {
assertThat(player.getCurrentWindowIndex()).isEqualTo(0);
assertThat(player.getCurrentPosition()).isEqualTo(0);
player.release();
}
@Test
@ -10532,6 +10534,51 @@ public final class ExoPlayerTest {
assertThat(player.getCurrentWindowIndex()).isEqualTo(1);
assertThat(player.getCurrentPosition()).isEqualTo(0);
player.release();
}
@Test
public void seekToNext_withNextWindow_seeksToNextWindow() {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource()));
player.seekToNext();
assertThat(player.getCurrentWindowIndex()).isEqualTo(1);
assertThat(player.getCurrentPosition()).isEqualTo(0);
player.release();
}
@Test
public void seekToNext_liveWindowWithoutNextWindow_seeksToLiveEdge() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Timeline timeline =
new FakeTimeline(
new TimelineWindowDefinition(
/* periodCount= */ 1,
/* id= */ 0,
/* isSeekable= */ true,
/* isDynamic= */ true,
/* isLive= */ true,
/* isPlaceholder= */ false,
/* durationUs= */ 1_000_000,
/* defaultPositionUs= */ 500_000,
TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
AdPlaybackState.NONE));
MediaSource mediaSource = new FakeMediaSource(timeline);
player.setMediaSource(mediaSource);
player.prepare();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(/* positionMs = */ 0);
player.seekToNext();
assertThat(player.getCurrentWindowIndex()).isEqualTo(0);
assertThat(player.getCurrentPosition()).isEqualTo(500);
player.release();
}
@Test