From 699579fd4e84e736c124c479e11573b4b147cd6c Mon Sep 17 00:00:00 2001 From: kimvde Date: Fri, 9 Jul 2021 12:02:11 +0100 Subject: [PATCH] Add seekToNext method to Player PiperOrigin-RevId: 383816880 --- RELEASENOTES.md | 9 ++-- .../google/android/exoplayer2/BasePlayer.java | 13 +++++ .../android/exoplayer2/ForwardingPlayer.java | 5 ++ .../com/google/android/exoplayer2/Player.java | 14 ++++++ .../android/exoplayer2/ExoPlayerTest.java | 49 ++++++++++++++++++- 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index cdefcb99da..8d1fc7850c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -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 diff --git a/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java b/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java index 62cc952cd9..251e4a523f 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/BasePlayer.java @@ -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)); diff --git a/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java b/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java index 8f14246283..966ddd8e69 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/ForwardingPlayer.java @@ -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); diff --git a/library/common/src/main/java/com/google/android/exoplayer2/Player.java b/library/common/src/main/java/com/google/android/exoplayer2/Player.java index 45a67291a9..254a67fe5b 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/Player.java @@ -1715,6 +1715,20 @@ public interface Player { */ void next(); + /** + * Seeks to a later position in the current or next window (if available). More precisely: + * + * + */ + 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. diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 845f8ec5e1..6032fb6568 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -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