From e828dfbd7c82f0f10b73c9f51182bd2d691095ad Mon Sep 17 00:00:00 2001 From: kimvde Date: Thu, 8 Jul 2021 18:03:49 +0100 Subject: [PATCH] Add getMaxSeekToPreviousPosition to Player PiperOrigin-RevId: 383656919 --- RELEASENOTES.md | 5 ++- .../exoplayer2/ext/cast/CastPlayer.java | 5 +++ .../google/android/exoplayer2/BasePlayer.java | 2 +- .../java/com/google/android/exoplayer2/C.java | 6 ++++ .../android/exoplayer2/ForwardingPlayer.java | 10 ++++++ .../com/google/android/exoplayer2/Player.java | 36 ++++++++++++++----- .../android/exoplayer2/ExoPlayerImpl.java | 5 +++ .../android/exoplayer2/SimpleExoPlayer.java | 6 ++++ .../analytics/AnalyticsCollector.java | 10 ++++++ .../analytics/AnalyticsListener.java | 13 +++++++ .../android/exoplayer2/ExoPlayerTest.java | 5 ++- .../exoplayer2/testutil/StubExoPlayer.java | 5 +++ 12 files changed, 94 insertions(+), 14 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 14ad71b3a3..ae18af495b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,7 +4,10 @@ * Core Library: * Add `needsReconfiguration` API to the `MediaCodecAdapter` interface. - * Add `seekForward`, `seekBack` and `seekToPrevious` methods to `Player`. + * Add `getSeekForwardIncrement`, `seekForward`, `getSeekBackIncrement` + and `seekBack` methods to `Player`. + * Add `getMaxSeekToPreviousPosition` and `seekToPrevious` methods to + `Player`. * Make `Player` depend on the new `PlaybackException` class instead of `ExoPlaybackException`: * `Player.getPlayerError` now returns a `PlaybackException`. 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 0a94d67fb2..29f0578613 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 @@ -458,6 +458,11 @@ public final class CastPlayer extends BasePlayer { return seekBackIncrementMs; } + @Override + public int getMaxSeekToPreviousPosition() { + return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS; + } + @Override public void setPlaybackParameters(PlaybackParameters playbackParameters) { // Unsupported by the RemoteMediaClient API. Do nothing. 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 a50b1935c3..ab62fe8835 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 @@ -155,7 +155,7 @@ public abstract class BasePlayer implements Player { if (hasPrevious) { previous(); } - } else if (hasPrevious && getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS) { + } else if (hasPrevious && getCurrentPosition() <= getMaxSeekToPreviousPosition()) { previous(); } else { seekTo(/* positionMs= */ 0); diff --git a/library/common/src/main/java/com/google/android/exoplayer2/C.java b/library/common/src/main/java/com/google/android/exoplayer2/C.java index dbd940ed32..8782ab2b99 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/C.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/C.java @@ -651,6 +651,12 @@ public final class C { /** A default seek back increment, in milliseconds. */ public static final long DEFAULT_SEEK_BACK_INCREMENT_MS = 5000; + /** + * A default maximum position for which a seek to previous will seek to the previous window, in + * milliseconds. + */ + public static final int DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS = 3000; + /** "cenc" scheme type name as defined in ISO/IEC 23001-7:2016. */ @SuppressWarnings("ConstantField") public static final String CENC_TYPE_cenc = "cenc"; 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 0b593f6cb9..8f14246283 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 @@ -282,6 +282,11 @@ public class ForwardingPlayer implements Player { player.seekToPrevious(); } + @Override + public int getMaxSeekToPreviousPosition() { + return player.getMaxSeekToPreviousPosition(); + } + @Override public boolean hasNext() { return player.hasNext(); @@ -711,6 +716,11 @@ public class ForwardingPlayer implements Player { eventListener.onSeekBackIncrementChanged(seekBackIncrementMs); } + @Override + public void onMaxSeekToPreviousPositionChanged(int maxSeekToPreviousPositionMs) { + eventListener.onMaxSeekToPreviousPositionChanged(maxSeekToPreviousPositionMs); + } + @Override public void onSeekProcessed() { eventListener.onSeekProcessed(); 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 1d41132c7c..a5707cde02 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 @@ -22,7 +22,6 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; import androidx.annotation.IntDef; -import androidx.annotation.IntRange; import androidx.annotation.Nullable; import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioListener; @@ -331,7 +330,7 @@ public interface Player { * * @param seekForwardIncrementMs The {@link #seekForward()} increment, in milliseconds. */ - default void onSeekForwardIncrementChanged(@IntRange(from = 1) long seekForwardIncrementMs) {} + default void onSeekForwardIncrementChanged(long seekForwardIncrementMs) {} /** * Called when the value of {@link #getSeekBackIncrement()} changes. @@ -341,7 +340,18 @@ public interface Player { * * @param seekBackIncrementMs The {@link #seekBack()} increment, in milliseconds. */ - default void onSeekBackIncrementChanged(@IntRange(from = 1) long seekBackIncrementMs) {} + default void onSeekBackIncrementChanged(long seekBackIncrementMs) {} + + /** + * Called when the value of {@link #getMaxSeekToPreviousPosition()} changes. + * + *

{@link #onEvents(Player, Events)} will also be called to report this event along with + * other events that happen in the same {@link Looper} message queue iteration. + * + * @param maxSeekToPreviousPositionMs The maximum position for which {@link #seekToPrevious()} + * seeks to the previous position, in milliseconds. + */ + default void onMaxSeekToPreviousPositionChanged(int maxSeekToPreviousPositionMs) {} /** * @deprecated Seeks are processed without delay. Listen to {@link @@ -884,9 +894,6 @@ public interface Player { default void onMetadata(Metadata metadata) {} } - /** The maximum position for which {@link #seekToPrevious()} seeks to the previous window. */ - int MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS = 3000; - /** * Playback state. One of {@link #STATE_IDLE}, {@link #STATE_BUFFERING}, {@link #STATE_READY} or * {@link #STATE_ENDED}. @@ -1100,7 +1107,8 @@ public interface Player { EVENT_MEDIA_METADATA_CHANGED, EVENT_PLAYLIST_METADATA_CHANGED, EVENT_SEEK_FORWARD_INCREMENT_CHANGED, - EVENT_SEEK_BACK_INCREMENT_CHANGED + EVENT_SEEK_BACK_INCREMENT_CHANGED, + EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED }) @interface EventFlags {} /** {@link #getCurrentTimeline()} changed. */ @@ -1144,6 +1152,8 @@ public interface Player { int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 17; /** {@link #getSeekBackIncrement()} changed. */ int EVENT_SEEK_BACK_INCREMENT_CHANGED = 18; + /** {@link #getMaxSeekToPreviousPosition()} changed. */ + int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = 19; /** * Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link @@ -1656,6 +1666,15 @@ public interface Player { */ void previous(); + /** + * Returns the maximum position for which {@link #seekToPrevious()} seeks to the previous window, + * in milliseconds. + * + * @return The maximum seek to previous position, in milliseconds. + * @see Listener#onMaxSeekToPreviousPositionChanged(int) + */ + int getMaxSeekToPreviousPosition(); + /** * Seeks to an earlier position in the current or previous window (if available). More precisely: * @@ -1670,8 +1689,7 @@ public interface Player { * *

  • Otherwise, if {@link #hasPrevious() a previous window exists} and the {@link * #getCurrentPosition() current position} is less than {@link - * #MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS}, seeks to the default position of the previous - * window. + * #getMaxSeekToPreviousPosition()}, seeks to the default position of the previous window. *
  • Otherwise, seeks to 0 in the current window. * */ 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 f416f8c218..d74c7bcf96 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 @@ -730,6 +730,11 @@ import java.util.concurrent.CopyOnWriteArraySet; return seekBackIncrementMs; } + @Override + public int getMaxSeekToPreviousPosition() { + return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS; + } + @Override public void setPlaybackParameters(PlaybackParameters playbackParameters) { if (playbackParameters == null) { 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 308e022065..1c949b53a9 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 @@ -1614,6 +1614,12 @@ public class SimpleExoPlayer extends BasePlayer return player.getSeekBackIncrement(); } + @Override + public int getMaxSeekToPreviousPosition() { + verifyApplicationThread(); + return player.getMaxSeekToPreviousPosition(); + } + @Override public void setPlaybackParameters(PlaybackParameters playbackParameters) { verifyApplicationThread(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java index da6ebf0275..1e29c1b56e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java @@ -760,6 +760,16 @@ public class AnalyticsCollector listener -> listener.onSeekBackIncrementChanged(eventTime, seekBackIncrementMs)); } + @Override + public void onMaxSeekToPreviousPositionChanged(int maxSeekToPreviousPositionMs) { + EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime(); + sendEvent( + eventTime, + AnalyticsListener.EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED, + listener -> + listener.onMaxSeekToPreviousPositionChanged(eventTime, maxSeekToPreviousPositionMs)); + } + @Override public void onMediaMetadataChanged(MediaMetadata mediaMetadata) { EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java index 53344dba00..8647ac3e5f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java @@ -260,6 +260,9 @@ public interface AnalyticsListener { int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = Player.EVENT_SEEK_FORWARD_INCREMENT_CHANGED; /** {@link Player#getSeekBackIncrement()} changed. */ int EVENT_SEEK_BACK_INCREMENT_CHANGED = Player.EVENT_SEEK_BACK_INCREMENT_CHANGED; + /** {@link Player#getMaxSeekToPreviousPosition()} changed. */ + int EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED = + Player.EVENT_MAX_SEEK_TO_PREVIOUS_POSITION_CHANGED; /** A source started loading data. */ int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events /** A source started completed loading data. */ @@ -611,6 +614,16 @@ public interface AnalyticsListener { */ default void onSeekBackIncrementChanged(EventTime eventTime, long seekBackIncrementMs) {} + /** + * Called when the maximum position for which {@link Player#seekToPrevious()} seeks to the + * previous window changes. + * + * @param eventTime The event time. + * @param maxSeekToPreviousPositionMs The maximum seek to previous position, in milliseconds. + */ + default void onMaxSeekToPreviousPositionChanged( + EventTime eventTime, int maxSeekToPreviousPositionMs) {} + /** * Called when the repeat mode changed. * 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 5c18b3105e..f730ed866f 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 @@ -40,7 +40,6 @@ import static com.google.android.exoplayer2.Player.COMMAND_SET_SHUFFLE_MODE; import static com.google.android.exoplayer2.Player.COMMAND_SET_SPEED_AND_PITCH; import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE; import static com.google.android.exoplayer2.Player.COMMAND_SET_VOLUME; -import static com.google.android.exoplayer2.Player.MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS; import static com.google.android.exoplayer2.Player.STATE_ENDED; import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil; import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition; @@ -10525,7 +10524,7 @@ public final class ExoPlayerTest { public void seekToPrevious_closeToStart_seeksToPreviousWindow() { ExoPlayer player = new TestExoPlayerBuilder(context).build(); player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource())); - player.seekTo(/* windowIndex= */ 1, /* positionMs= */ MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS); + player.seekTo(/* windowIndex= */ 1, C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS); player.seekToPrevious(); @@ -10537,7 +10536,7 @@ public final class ExoPlayerTest { public void seekToPrevious_notCloseToStart_seeksToZero() { ExoPlayer player = new TestExoPlayerBuilder(context).build(); player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource())); - player.seekTo(/* windowIndex= */ 1, /* positionMs= */ MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS + 1); + player.seekTo(/* windowIndex= */ 1, C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS + 1); player.seekToPrevious(); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java index 8060a91124..d4e1d314bc 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/StubExoPlayer.java @@ -309,6 +309,11 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer { throw new UnsupportedOperationException(); } + @Override + public int getMaxSeekToPreviousPosition() { + throw new UnsupportedOperationException(); + } + @Override public void setPlaybackParameters(PlaybackParameters playbackParameters) { throw new UnsupportedOperationException();