Add getMaxSeekToPreviousPosition to Player

PiperOrigin-RevId: 383656919
This commit is contained in:
kimvde 2021-07-08 18:03:49 +01:00 committed by kim-vde
parent c4e99902c3
commit e828dfbd7c
12 changed files with 94 additions and 14 deletions

View file

@ -4,7 +4,10 @@
* Core Library: * Core Library:
* Add `needsReconfiguration` API to the `MediaCodecAdapter` interface. * 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 * Make `Player` depend on the new `PlaybackException` class instead of
`ExoPlaybackException`: `ExoPlaybackException`:
* `Player.getPlayerError` now returns a `PlaybackException`. * `Player.getPlayerError` now returns a `PlaybackException`.

View file

@ -458,6 +458,11 @@ public final class CastPlayer extends BasePlayer {
return seekBackIncrementMs; return seekBackIncrementMs;
} }
@Override
public int getMaxSeekToPreviousPosition() {
return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
}
@Override @Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) { public void setPlaybackParameters(PlaybackParameters playbackParameters) {
// Unsupported by the RemoteMediaClient API. Do nothing. // Unsupported by the RemoteMediaClient API. Do nothing.

View file

@ -155,7 +155,7 @@ public abstract class BasePlayer implements Player {
if (hasPrevious) { if (hasPrevious) {
previous(); previous();
} }
} else if (hasPrevious && getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS) { } else if (hasPrevious && getCurrentPosition() <= getMaxSeekToPreviousPosition()) {
previous(); previous();
} else { } else {
seekTo(/* positionMs= */ 0); seekTo(/* positionMs= */ 0);

View file

@ -651,6 +651,12 @@ public final class C {
/** A default seek back increment, in milliseconds. */ /** A default seek back increment, in milliseconds. */
public static final long DEFAULT_SEEK_BACK_INCREMENT_MS = 5000; 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. */ /** "cenc" scheme type name as defined in ISO/IEC 23001-7:2016. */
@SuppressWarnings("ConstantField") @SuppressWarnings("ConstantField")
public static final String CENC_TYPE_cenc = "cenc"; public static final String CENC_TYPE_cenc = "cenc";

View file

@ -282,6 +282,11 @@ public class ForwardingPlayer implements Player {
player.seekToPrevious(); player.seekToPrevious();
} }
@Override
public int getMaxSeekToPreviousPosition() {
return player.getMaxSeekToPreviousPosition();
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return player.hasNext(); return player.hasNext();
@ -711,6 +716,11 @@ public class ForwardingPlayer implements Player {
eventListener.onSeekBackIncrementChanged(seekBackIncrementMs); eventListener.onSeekBackIncrementChanged(seekBackIncrementMs);
} }
@Override
public void onMaxSeekToPreviousPositionChanged(int maxSeekToPreviousPositionMs) {
eventListener.onMaxSeekToPreviousPositionChanged(maxSeekToPreviousPositionMs);
}
@Override @Override
public void onSeekProcessed() { public void onSeekProcessed() {
eventListener.onSeekProcessed(); eventListener.onSeekProcessed();

View file

@ -22,7 +22,6 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import android.view.TextureView; import android.view.TextureView;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.audio.AudioListener; import com.google.android.exoplayer2.audio.AudioListener;
@ -331,7 +330,7 @@ public interface Player {
* *
* @param seekForwardIncrementMs The {@link #seekForward()} increment, in milliseconds. * @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. * Called when the value of {@link #getSeekBackIncrement()} changes.
@ -341,7 +340,18 @@ public interface Player {
* *
* @param seekBackIncrementMs The {@link #seekBack()} increment, in milliseconds. * @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.
*
* <p>{@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 * @deprecated Seeks are processed without delay. Listen to {@link
@ -884,9 +894,6 @@ public interface Player {
default void onMetadata(Metadata metadata) {} 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 * Playback state. One of {@link #STATE_IDLE}, {@link #STATE_BUFFERING}, {@link #STATE_READY} or
* {@link #STATE_ENDED}. * {@link #STATE_ENDED}.
@ -1100,7 +1107,8 @@ public interface Player {
EVENT_MEDIA_METADATA_CHANGED, EVENT_MEDIA_METADATA_CHANGED,
EVENT_PLAYLIST_METADATA_CHANGED, EVENT_PLAYLIST_METADATA_CHANGED,
EVENT_SEEK_FORWARD_INCREMENT_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 {} @interface EventFlags {}
/** {@link #getCurrentTimeline()} changed. */ /** {@link #getCurrentTimeline()} changed. */
@ -1144,6 +1152,8 @@ public interface Player {
int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 17; int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = 17;
/** {@link #getSeekBackIncrement()} changed. */ /** {@link #getSeekBackIncrement()} changed. */
int EVENT_SEEK_BACK_INCREMENT_CHANGED = 18; 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 * 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(); 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: * Seeks to an earlier position in the current or previous window (if available). More precisely:
* *
@ -1670,8 +1689,7 @@ public interface Player {
* </ul> * </ul>
* <li>Otherwise, if {@link #hasPrevious() a previous window exists} and the {@link * <li>Otherwise, if {@link #hasPrevious() a previous window exists} and the {@link
* #getCurrentPosition() current position} is less than {@link * #getCurrentPosition() current position} is less than {@link
* #MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS}, seeks to the default position of the previous * #getMaxSeekToPreviousPosition()}, seeks to the default position of the previous window.
* window.
* <li>Otherwise, seeks to 0 in the current window. * <li>Otherwise, seeks to 0 in the current window.
* </ul> * </ul>
*/ */

View file

@ -730,6 +730,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
return seekBackIncrementMs; return seekBackIncrementMs;
} }
@Override
public int getMaxSeekToPreviousPosition() {
return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
}
@Override @Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) { public void setPlaybackParameters(PlaybackParameters playbackParameters) {
if (playbackParameters == null) { if (playbackParameters == null) {

View file

@ -1614,6 +1614,12 @@ public class SimpleExoPlayer extends BasePlayer
return player.getSeekBackIncrement(); return player.getSeekBackIncrement();
} }
@Override
public int getMaxSeekToPreviousPosition() {
verifyApplicationThread();
return player.getMaxSeekToPreviousPosition();
}
@Override @Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) { public void setPlaybackParameters(PlaybackParameters playbackParameters) {
verifyApplicationThread(); verifyApplicationThread();

View file

@ -760,6 +760,16 @@ public class AnalyticsCollector
listener -> listener.onSeekBackIncrementChanged(eventTime, seekBackIncrementMs)); 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 @Override
public void onMediaMetadataChanged(MediaMetadata mediaMetadata) { public void onMediaMetadataChanged(MediaMetadata mediaMetadata) {
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime(); EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();

View file

@ -260,6 +260,9 @@ public interface AnalyticsListener {
int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = Player.EVENT_SEEK_FORWARD_INCREMENT_CHANGED; int EVENT_SEEK_FORWARD_INCREMENT_CHANGED = Player.EVENT_SEEK_FORWARD_INCREMENT_CHANGED;
/** {@link Player#getSeekBackIncrement()} changed. */ /** {@link Player#getSeekBackIncrement()} changed. */
int EVENT_SEEK_BACK_INCREMENT_CHANGED = Player.EVENT_SEEK_BACK_INCREMENT_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. */ /** A source started loading data. */
int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events
/** A source started completed loading data. */ /** A source started completed loading data. */
@ -611,6 +614,16 @@ public interface AnalyticsListener {
*/ */
default void onSeekBackIncrementChanged(EventTime eventTime, long seekBackIncrementMs) {} 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. * Called when the repeat mode changed.
* *

View file

@ -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_SPEED_AND_PITCH;
import static com.google.android.exoplayer2.Player.COMMAND_SET_VIDEO_SURFACE; 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.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.Player.STATE_ENDED;
import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil; import static com.google.android.exoplayer2.robolectric.RobolectricUtil.runMainLooperUntil;
import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition; import static com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilPosition;
@ -10525,7 +10524,7 @@ public final class ExoPlayerTest {
public void seekToPrevious_closeToStart_seeksToPreviousWindow() { public void seekToPrevious_closeToStart_seeksToPreviousWindow() {
ExoPlayer player = new TestExoPlayerBuilder(context).build(); ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource())); 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(); player.seekToPrevious();
@ -10537,7 +10536,7 @@ public final class ExoPlayerTest {
public void seekToPrevious_notCloseToStart_seeksToZero() { public void seekToPrevious_notCloseToStart_seeksToZero() {
ExoPlayer player = new TestExoPlayerBuilder(context).build(); ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addMediaSources(ImmutableList.of(new FakeMediaSource(), new FakeMediaSource())); 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(); player.seekToPrevious();

View file

@ -309,6 +309,11 @@ public class StubExoPlayer extends BasePlayer implements ExoPlayer {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public int getMaxSeekToPreviousPosition() {
throw new UnsupportedOperationException();
}
@Override @Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) { public void setPlaybackParameters(PlaybackParameters playbackParameters) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();