mirror of
https://github.com/samsonjs/media.git
synced 2026-04-20 13:45:47 +00:00
Add seekToPrevious method to Player
PiperOrigin-RevId: 383623440
This commit is contained in:
parent
d9618b5104
commit
c4e99902c3
5 changed files with 73 additions and 1 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
* Core Library:
|
||||
* Add `needsReconfiguration` API to the `MediaCodecAdapter` interface.
|
||||
* Add `seekForward` and `seekBack` methods to `Player`.
|
||||
* Add `seekForward`, `seekBack` and `seekToPrevious` methods to `Player`.
|
||||
* Make `Player` depend on the new `PlaybackException` class instead of
|
||||
`ExoPlaybackException`:
|
||||
* `Player.getPlayerError` now returns a `PlaybackException`.
|
||||
|
|
|
|||
|
|
@ -144,6 +144,24 @@ public abstract class BasePlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void seekToPrevious() {
|
||||
Timeline timeline = getCurrentTimeline();
|
||||
if (timeline.isEmpty() || isPlayingAd()) {
|
||||
return;
|
||||
}
|
||||
boolean hasPrevious = hasPrevious();
|
||||
if (isCurrentWindowLive() && !isCurrentWindowSeekable()) {
|
||||
if (hasPrevious) {
|
||||
previous();
|
||||
}
|
||||
} else if (hasPrevious && getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS_MS) {
|
||||
previous();
|
||||
} else {
|
||||
seekTo(/* positionMs= */ 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
return getNextWindowIndex() != C.INDEX_UNSET;
|
||||
|
|
|
|||
|
|
@ -277,6 +277,11 @@ public class ForwardingPlayer implements Player {
|
|||
player.previous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekToPrevious() {
|
||||
player.seekToPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return player.hasNext();
|
||||
|
|
|
|||
|
|
@ -884,6 +884,9 @@ 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}.
|
||||
|
|
@ -1653,6 +1656,27 @@ public interface Player {
|
|||
*/
|
||||
void previous();
|
||||
|
||||
/**
|
||||
* Seeks to an earlier position in the current or previous window (if available). More precisely:
|
||||
*
|
||||
* <ul>
|
||||
* <li>If the timeline is empty or seeking is not possible, does nothing.
|
||||
* <li>Otherwise, if the current window is {@link #isCurrentWindowLive() live} and {@link
|
||||
* #isCurrentWindowSeekable() unseekable}, then:
|
||||
* <ul>
|
||||
* <li>If {@link #hasPrevious() a previous window exists}, seeks to the default position
|
||||
* of the previous window.
|
||||
* <li>Otherwise, does nothing.
|
||||
* </ul>
|
||||
* <li>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.
|
||||
* <li>Otherwise, seeks to 0 in the current window.
|
||||
* </ul>
|
||||
*/
|
||||
void seekToPrevious();
|
||||
|
||||
/**
|
||||
* Returns whether a next window exists, which may depend on the current repeat mode and whether
|
||||
* shuffle mode is enabled.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ 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;
|
||||
|
|
@ -10520,6 +10521,30 @@ public final class ExoPlayerTest {
|
|||
player.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
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.seekToPrevious();
|
||||
|
||||
assertThat(player.getCurrentWindowIndex()).isEqualTo(0);
|
||||
assertThat(player.getCurrentPosition()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
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.seekToPrevious();
|
||||
|
||||
assertThat(player.getCurrentWindowIndex()).isEqualTo(1);
|
||||
assertThat(player.getCurrentPosition()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stop_doesNotCallOnPositionDiscontinuity() throws Exception {
|
||||
ExoPlayer player = new TestExoPlayerBuilder(context).build();
|
||||
|
|
|
|||
Loading…
Reference in a new issue