Add hook for modifying or cancelling a user invoked seek

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142007001
This commit is contained in:
olly 2016-12-14 05:33:36 -08:00 committed by Oliver Woodman
parent fc93940463
commit 31e2fa8597
3 changed files with 81 additions and 11 deletions

View file

@ -330,17 +330,19 @@ public interface ExoPlayer {
/**
* Seeks to a position specified in milliseconds in the current window.
*
* @param windowPositionMs The seek position in the current window.
* @param positionMs The seek position in the current window, or {@link C#TIME_UNSET} to seek to
* the window's default position.
*/
void seekTo(long windowPositionMs);
void seekTo(long positionMs);
/**
* Seeks to a position specified in milliseconds in the specified window.
*
* @param windowIndex The index of the window.
* @param windowPositionMs The seek position in the specified window.
* @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek to
* the window's default position.
*/
void seekTo(int windowIndex, long windowPositionMs);
void seekTo(int windowIndex, long positionMs);
/**
* Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention

View file

@ -148,14 +148,45 @@ public class PlaybackControlView extends FrameLayout {
* Listener to be notified about changes of the visibility of the UI control.
*/
public interface VisibilityListener {
/**
* Called when the visibility changes.
*
* @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}.
*/
void onVisibilityChange(int visibility);
}
/**
* Dispatches seek operations to the player.
*/
public interface SeekDispatcher {
/**
* @param player The player to seek.
* @param windowIndex The index of the window.
* @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek
* to the window's default position.
* @return True if the seek was dispatched. False otherwise.
*/
boolean dispatchSeek(ExoPlayer player, int windowIndex, long positionMs);
}
/**
* Default {@link SeekDispatcher} that dispatches seeks to the player without modification.
*/
public static final SeekDispatcher DEFAULT_SEEK_DISPATCHER = new SeekDispatcher() {
@Override
public boolean dispatchSeek(ExoPlayer player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
return true;
}
};
public static final int DEFAULT_FAST_FORWARD_MS = 15000;
public static final int DEFAULT_REWIND_MS = 5000;
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
@ -178,6 +209,7 @@ public class PlaybackControlView extends FrameLayout {
private final Timeline.Window currentWindow;
private ExoPlayer player;
private SeekDispatcher seekDispatcher;
private VisibilityListener visibilityListener;
private boolean isAttachedToWindow;
@ -234,6 +266,7 @@ public class PlaybackControlView extends FrameLayout {
formatBuilder = new StringBuilder();
formatter = new Formatter(formatBuilder, Locale.getDefault());
componentListener = new ComponentListener();
seekDispatcher = DEFAULT_SEEK_DISPATCHER;
LayoutInflater.from(context).inflate(controllerLayoutId, this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
@ -306,6 +339,16 @@ public class PlaybackControlView extends FrameLayout {
this.visibilityListener = listener;
}
/**
* Sets the {@link SeekDispatcher}.
*
* @param seekDispatcher The {@link SeekDispatcher}, or null to use
* {@link #DEFAULT_SEEK_DISPATCHER}.
*/
public void setSeekDispatcher(SeekDispatcher seekDispatcher) {
this.seekDispatcher = seekDispatcher == null ? DEFAULT_SEEK_DISPATCHER : seekDispatcher;
}
/**
* Sets the rewind increment in milliseconds.
*
@ -550,9 +593,9 @@ public class PlaybackControlView extends FrameLayout {
currentTimeline.getWindow(currentWindowIndex, currentWindow);
if (currentWindowIndex > 0 && (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|| (currentWindow.isDynamic && !currentWindow.isSeekable))) {
player.seekToDefaultPosition(currentWindowIndex - 1);
seekTo(currentWindowIndex - 1, C.TIME_UNSET);
} else {
player.seekTo(0);
seekTo(0);
}
}
@ -563,9 +606,9 @@ public class PlaybackControlView extends FrameLayout {
}
int currentWindowIndex = player.getCurrentWindowIndex();
if (currentWindowIndex < currentTimeline.getWindowCount() - 1) {
player.seekToDefaultPosition(currentWindowIndex + 1);
seekTo(currentWindowIndex + 1, C.TIME_UNSET);
} else if (currentTimeline.getWindow(currentWindowIndex, currentWindow, false).isDynamic) {
player.seekToDefaultPosition();
seekTo(currentWindowIndex, C.TIME_UNSET);
}
}
@ -573,14 +616,27 @@ public class PlaybackControlView extends FrameLayout {
if (rewindMs <= 0) {
return;
}
player.seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
}
private void fastForward() {
if (fastForwardMs <= 0) {
return;
}
player.seekTo(Math.min(player.getCurrentPosition() + fastForwardMs, player.getDuration()));
seekTo(Math.min(player.getCurrentPosition() + fastForwardMs, player.getDuration()));
}
private void seekTo(long positionMs) {
seekTo(player.getCurrentWindowIndex(), positionMs);
}
private void seekTo(int windowIndex, long positionMs) {
boolean dispatched = seekDispatcher.dispatchSeek(player, windowIndex, positionMs);
if (!dispatched) {
// The seek wasn't dispatched. If the progress bar was dragged by the user to perform the
// seek then it'll now be in the wrong position. Trigger a progress update to snap it back.
updateProgress();
}
}
@Override
@ -688,7 +744,7 @@ public class PlaybackControlView extends FrameLayout {
public void onStopTrackingTouch(SeekBar seekBar) {
dragging = false;
if (player != null) {
player.seekTo(positionValue(seekBar.getProgress()));
seekTo(positionValue(seekBar.getProgress()));
}
hideAfterTimeout();
}

View file

@ -44,6 +44,7 @@ import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
import com.google.android.exoplayer2.ui.PlaybackControlView.SeekDispatcher;
import com.google.android.exoplayer2.util.Assertions;
import java.util.List;
@ -440,6 +441,17 @@ public final class SimpleExoPlayerView extends FrameLayout {
controller.setVisibilityListener(listener);
}
/**
* Sets the {@link SeekDispatcher}.
*
* @param seekDispatcher The {@link SeekDispatcher}, or null to use
* {@link PlaybackControlView#DEFAULT_SEEK_DISPATCHER}.
*/
public void setSeekDispatcher(SeekDispatcher seekDispatcher) {
Assertions.checkState(controller != null);
controller.setSeekDispatcher(seekDispatcher);
}
/**
* Sets the rewind increment in milliseconds.
*