From b2e0a365d35feb5e5edb6439293f056ab022432c Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 26 Sep 2018 03:27:52 -0700 Subject: [PATCH] Add convenience methods player.next() and player.previous() This simplifies code skipping items in a playlist programatically. Issue:#4863 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=214580742 --- RELEASENOTES.md | 3 ++ .../exoplayer2/ext/cast/CastPlayer.java | 26 ++++++++++++++++ .../android/exoplayer2/ExoPlayerImpl.java | 26 ++++++++++++++++ .../com/google/android/exoplayer2/Player.java | 26 ++++++++++++++++ .../android/exoplayer2/SimpleExoPlayer.java | 30 +++++++++++++++++++ .../exoplayer2/testutil/StubExoPlayer.java | 20 +++++++++++++ 6 files changed, 131 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 032596a425..bcf05590bf 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,6 +8,9 @@ * Fix an issue where audio and video would desynchronize when playing concatenations of gapless content ([#4559](https://github.com/google/ExoPlayer/issues/4559)). +* Add convenience methods `Player.next`, `Player.previous`, `Player.hasNext` + and `Player.hasPrevious` + ([#4863](https://github.com/google/ExoPlayer/issues/4863)). ### 2.9.0 ### diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java index 97b05e3f0a..f630ea1628 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastPlayer.java @@ -382,6 +382,32 @@ public final class CastPlayer implements Player { } } + @Override + public boolean hasPrevious() { + return getPreviousWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void previous() { + int previousWindowIndex = getPreviousWindowIndex(); + if (previousWindowIndex != C.INDEX_UNSET) { + seekToDefaultPosition(previousWindowIndex); + } + } + + @Override + public boolean hasNext() { + return getNextWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void next() { + int nextWindowIndex = getPreviousWindowIndex(); + if (nextWindowIndex != C.INDEX_UNSET) { + seekToDefaultPosition(nextWindowIndex); + } + } + @Override public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) { // Unsupported by the RemoteMediaClient API. Do nothing. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index 027f316493..83854ffca9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -348,6 +348,32 @@ import java.util.concurrent.CopyOnWriteArraySet; } } + @Override + public boolean hasPrevious() { + return getPreviousWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void previous() { + int previousWindowIndex = getPreviousWindowIndex(); + if (previousWindowIndex != C.INDEX_UNSET) { + seekToDefaultPosition(previousWindowIndex); + } + } + + @Override + public boolean hasNext() { + return getNextWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void next() { + int nextWindowIndex = getPreviousWindowIndex(); + if (nextWindowIndex != C.INDEX_UNSET) { + seekToDefaultPosition(nextWindowIndex); + } + } + @Override public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) { if (playbackParameters == null) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Player.java b/library/core/src/main/java/com/google/android/exoplayer2/Player.java index d4b965dbd6..3640928c54 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Player.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Player.java @@ -655,6 +655,32 @@ public interface Player { */ void seekTo(int windowIndex, long positionMs); + /** + * Returns whether a previous window exists, which may depend on the current repeat mode and + * whether shuffle mode is enabled. + */ + boolean hasPrevious(); + + /** + * Seeks to the default position of the previous window in the timeline, which may depend on the + * current repeat mode and whether shuffle mode is enabled. Does nothing if {@link #hasPrevious()} + * is {@code false}. + */ + void previous(); + + /** + * Returns whether a next window exists, which may depend on the current repeat mode and whether + * shuffle mode is enabled. + */ + boolean hasNext(); + + /** + * Seeks to the default position of the next window in the timeline, which may depend on the + * current repeat mode and whether shuffle mode is enabled. Does nothing if {@link #hasNext()} is + * {@code false}. + */ + void next(); + /** * Attempts to set the playback parameters. Passing {@code null} sets the parameters to the * default, {@link PlaybackParameters#DEFAULT}, which means there is no speed or pitch adjustment. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index 39f1655ab5..7e5feec024 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -955,6 +955,36 @@ public class SimpleExoPlayer player.seekTo(windowIndex, positionMs); } + @Override + public boolean hasPrevious() { + verifyApplicationThread(); + return getPreviousWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void previous() { + verifyApplicationThread(); + if (hasPrevious()) { + analyticsCollector.notifySeekStarted(); + player.previous(); + } + } + + @Override + public boolean hasNext() { + verifyApplicationThread(); + return getNextWindowIndex() != C.INDEX_UNSET; + } + + @Override + public void next() { + verifyApplicationThread(); + if (hasNext()) { + analyticsCollector.notifySeekStarted(); + player.next(); + } + } + @Override public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) { verifyApplicationThread(); diff --git a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java index f1349c1158..7882c7d16c 100644 --- a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java +++ b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java @@ -149,6 +149,26 @@ public abstract class StubExoPlayer implements ExoPlayer { throw new UnsupportedOperationException(); } + @Override + public boolean hasPrevious() { + throw new UnsupportedOperationException(); + } + + @Override + public void previous() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + throw new UnsupportedOperationException(); + } + + @Override + public void next() { + throw new UnsupportedOperationException(); + } + @Override public void setPlaybackParameters(PlaybackParameters playbackParameters) { throw new UnsupportedOperationException();