Commit 31e2fa85 by olly Committed by Oliver Woodman

Add hook for modifying or cancelling a user invoked seek

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142007001
parent fc939404
...@@ -330,17 +330,19 @@ public interface ExoPlayer { ...@@ -330,17 +330,19 @@ public interface ExoPlayer {
/** /**
* Seeks to a position specified in milliseconds in the current window. * 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. * Seeks to a position specified in milliseconds in the specified window.
* *
* @param windowIndex The index of the 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 * Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention
......
...@@ -148,14 +148,45 @@ public class PlaybackControlView extends FrameLayout { ...@@ -148,14 +148,45 @@ public class PlaybackControlView extends FrameLayout {
* Listener to be notified about changes of the visibility of the UI control. * Listener to be notified about changes of the visibility of the UI control.
*/ */
public interface VisibilityListener { public interface VisibilityListener {
/** /**
* Called when the visibility changes. * Called when the visibility changes.
* *
* @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}. * @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}.
*/ */
void onVisibilityChange(int visibility); 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_FAST_FORWARD_MS = 15000;
public static final int DEFAULT_REWIND_MS = 5000; public static final int DEFAULT_REWIND_MS = 5000;
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000; public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
...@@ -178,6 +209,7 @@ public class PlaybackControlView extends FrameLayout { ...@@ -178,6 +209,7 @@ public class PlaybackControlView extends FrameLayout {
private final Timeline.Window currentWindow; private final Timeline.Window currentWindow;
private ExoPlayer player; private ExoPlayer player;
private SeekDispatcher seekDispatcher;
private VisibilityListener visibilityListener; private VisibilityListener visibilityListener;
private boolean isAttachedToWindow; private boolean isAttachedToWindow;
...@@ -234,6 +266,7 @@ public class PlaybackControlView extends FrameLayout { ...@@ -234,6 +266,7 @@ public class PlaybackControlView extends FrameLayout {
formatBuilder = new StringBuilder(); formatBuilder = new StringBuilder();
formatter = new Formatter(formatBuilder, Locale.getDefault()); formatter = new Formatter(formatBuilder, Locale.getDefault());
componentListener = new ComponentListener(); componentListener = new ComponentListener();
seekDispatcher = DEFAULT_SEEK_DISPATCHER;
LayoutInflater.from(context).inflate(controllerLayoutId, this); LayoutInflater.from(context).inflate(controllerLayoutId, this);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
...@@ -307,6 +340,16 @@ public class PlaybackControlView extends FrameLayout { ...@@ -307,6 +340,16 @@ public class PlaybackControlView extends FrameLayout {
} }
/** /**
* 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. * Sets the rewind increment in milliseconds.
* *
* @param rewindMs The rewind increment in milliseconds. A non-positive value will cause the * @param rewindMs The rewind increment in milliseconds. A non-positive value will cause the
...@@ -550,9 +593,9 @@ public class PlaybackControlView extends FrameLayout { ...@@ -550,9 +593,9 @@ public class PlaybackControlView extends FrameLayout {
currentTimeline.getWindow(currentWindowIndex, currentWindow); currentTimeline.getWindow(currentWindowIndex, currentWindow);
if (currentWindowIndex > 0 && (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS if (currentWindowIndex > 0 && (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|| (currentWindow.isDynamic && !currentWindow.isSeekable))) { || (currentWindow.isDynamic && !currentWindow.isSeekable))) {
player.seekToDefaultPosition(currentWindowIndex - 1); seekTo(currentWindowIndex - 1, C.TIME_UNSET);
} else { } else {
player.seekTo(0); seekTo(0);
} }
} }
...@@ -563,9 +606,9 @@ public class PlaybackControlView extends FrameLayout { ...@@ -563,9 +606,9 @@ public class PlaybackControlView extends FrameLayout {
} }
int currentWindowIndex = player.getCurrentWindowIndex(); int currentWindowIndex = player.getCurrentWindowIndex();
if (currentWindowIndex < currentTimeline.getWindowCount() - 1) { if (currentWindowIndex < currentTimeline.getWindowCount() - 1) {
player.seekToDefaultPosition(currentWindowIndex + 1); seekTo(currentWindowIndex + 1, C.TIME_UNSET);
} else if (currentTimeline.getWindow(currentWindowIndex, currentWindow, false).isDynamic) { } else if (currentTimeline.getWindow(currentWindowIndex, currentWindow, false).isDynamic) {
player.seekToDefaultPosition(); seekTo(currentWindowIndex, C.TIME_UNSET);
} }
} }
...@@ -573,14 +616,27 @@ public class PlaybackControlView extends FrameLayout { ...@@ -573,14 +616,27 @@ public class PlaybackControlView extends FrameLayout {
if (rewindMs <= 0) { if (rewindMs <= 0) {
return; return;
} }
player.seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0)); seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
} }
private void fastForward() { private void fastForward() {
if (fastForwardMs <= 0) { if (fastForwardMs <= 0) {
return; 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 @Override
...@@ -688,7 +744,7 @@ public class PlaybackControlView extends FrameLayout { ...@@ -688,7 +744,7 @@ public class PlaybackControlView extends FrameLayout {
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
dragging = false; dragging = false;
if (player != null) { if (player != null) {
player.seekTo(positionValue(seekBar.getProgress())); seekTo(positionValue(seekBar.getProgress()));
} }
hideAfterTimeout(); hideAfterTimeout();
} }
......
...@@ -44,6 +44,7 @@ import com.google.android.exoplayer2.text.TextRenderer; ...@@ -44,6 +44,7 @@ import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
import com.google.android.exoplayer2.ui.PlaybackControlView.SeekDispatcher;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.util.List; import java.util.List;
...@@ -441,6 +442,17 @@ public final class SimpleExoPlayerView extends FrameLayout { ...@@ -441,6 +442,17 @@ public final class SimpleExoPlayerView extends FrameLayout {
} }
/** /**
* 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. * Sets the rewind increment in milliseconds.
* *
* @param rewindMs The rewind increment in milliseconds. * @param rewindMs The rewind increment in milliseconds.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment