mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add window based methods to ExoPlayer
- This change also enables seeking in live windows in the ExoPlayer demo app. - The added playlist doesn't transition properly by itself, but for manual transitions it works correctly, and demonstrates seeking into a default position. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130515880
This commit is contained in:
parent
76bb10428b
commit
b35648eafb
8 changed files with 320 additions and 111 deletions
|
|
@ -281,7 +281,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
|
||||||
player.setVideoListener(this);
|
player.setVideoListener(this);
|
||||||
player.setVideoSurfaceHolder(surfaceView.getHolder());
|
player.setVideoSurfaceHolder(surfaceView.getHolder());
|
||||||
if (shouldRestorePosition) {
|
if (shouldRestorePosition) {
|
||||||
player.seekTo(playerPeriodIndex, playerPosition);
|
player.seekInPeriod(playerPeriodIndex, playerPosition);
|
||||||
}
|
}
|
||||||
player.setPlayWhenReady(true);
|
player.setPlayWhenReady(true);
|
||||||
mediaController.setMediaPlayer(new PlayerControl(player));
|
mediaController.setMediaPlayer(new PlayerControl(player));
|
||||||
|
|
@ -371,7 +371,7 @@ public class PlayerActivity extends Activity implements OnKeyListener, OnTouchLi
|
||||||
debugViewHelper.stop();
|
debugViewHelper.stop();
|
||||||
debugViewHelper = null;
|
debugViewHelper = null;
|
||||||
playerPeriodIndex = player.getCurrentPeriodIndex();
|
playerPeriodIndex = player.getCurrentPeriodIndex();
|
||||||
playerPosition = player.getCurrentPosition();
|
playerPosition = player.getCurrentPositionInPeriod();
|
||||||
shouldRestorePosition = false;
|
shouldRestorePosition = false;
|
||||||
Timeline playerTimeline = player.getCurrentTimeline();
|
Timeline playerTimeline = player.getCurrentTimeline();
|
||||||
if (playerTimeline != null) {
|
if (playerTimeline != null) {
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ public interface ExoPlayer {
|
||||||
* @param mediaSource The {@link MediaSource} to play.
|
* @param mediaSource The {@link MediaSource} to play.
|
||||||
* @param resetPosition Whether the playback position should be reset to the source's default
|
* @param resetPosition Whether the playback position should be reset to the source's default
|
||||||
* position. If false, playback will start from the position defined by
|
* position. If false, playback will start from the position defined by
|
||||||
* {@link #getCurrentPeriodIndex()} and {@link #getCurrentPosition()}.
|
* {@link #getCurrentPeriodIndex()} and {@link #getCurrentPositionInPeriod()}.
|
||||||
*/
|
*/
|
||||||
void setMediaSource(MediaSource mediaSource, boolean resetPosition);
|
void setMediaSource(MediaSource mediaSource, boolean resetPosition);
|
||||||
|
|
||||||
|
|
@ -278,26 +278,52 @@ public interface ExoPlayer {
|
||||||
*
|
*
|
||||||
* @param positionMs The seek position.
|
* @param positionMs The seek position.
|
||||||
*/
|
*/
|
||||||
void seekTo(long positionMs);
|
void seekInCurrentPeriod(long positionMs);
|
||||||
|
|
||||||
/**
|
|
||||||
* Seeks to a position specified in milliseconds in the specified period.
|
|
||||||
*
|
|
||||||
* @param periodIndex The index of the period to seek to.
|
|
||||||
* @param positionMs The seek position relative to the start of the specified period.
|
|
||||||
*/
|
|
||||||
void seekTo(int periodIndex, long positionMs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seeks to the default position associated with the specified period. The position can depend on
|
* Seeks to the default position associated with the specified period. The position can depend on
|
||||||
* the type of source passed to {@link #setMediaSource(MediaSource)}. For live streams it will
|
* the type of source passed to {@link #setMediaSource(MediaSource)}. For live streams it will
|
||||||
* typically be the live edge. For other types of streams it will typically be the start of the
|
* typically be the live edge of the window to which the period belongs. For other streams it will
|
||||||
* stream.
|
* typically be the start of the period.
|
||||||
*
|
*
|
||||||
* @param periodIndex The index of the period whose associated default position should be seeked
|
* @param periodIndex The index of the period whose associated default position should be seeked
|
||||||
* to.
|
* to.
|
||||||
*/
|
*/
|
||||||
void seekToDefaultPosition(int periodIndex);
|
void seekToDefaultPositionForPeriod(int periodIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seeks to a position specified in milliseconds in the specified period.
|
||||||
|
*
|
||||||
|
* @param periodIndex The index of the period.
|
||||||
|
* @param positionMs The seek position relative to the start of the period.
|
||||||
|
*/
|
||||||
|
void seekInPeriod(int periodIndex, long positionMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seeks to a position specified in milliseconds in the current window.
|
||||||
|
*
|
||||||
|
* @param positionMs The seek position.
|
||||||
|
*/
|
||||||
|
void seekInCurrentWindow(long positionMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seeks to the default position associated with the specified window. The position can depend on
|
||||||
|
* the type of source passed to {@link #setMediaSource(MediaSource)}. For live streams it will
|
||||||
|
* typically be the live edge of the window. For other streams it will typically be the start of
|
||||||
|
* the window.
|
||||||
|
*
|
||||||
|
* @param windowIndex The index of the window whose associated default position should be seeked
|
||||||
|
* to.
|
||||||
|
*/
|
||||||
|
void seekToDefaultPositionForWindow(int windowIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seeks to a position specified in milliseconds in the specified seek window.
|
||||||
|
*
|
||||||
|
* @param seekWindowIndex The index of the seek window.
|
||||||
|
* @param positionMs The seek position relative to the start of the window.
|
||||||
|
*/
|
||||||
|
void seekInWindow(int seekWindowIndex, 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
|
||||||
|
|
@ -334,22 +360,6 @@ public interface ExoPlayer {
|
||||||
*/
|
*/
|
||||||
void blockingSendMessages(ExoPlayerMessage... messages);
|
void blockingSendMessages(ExoPlayerMessage... messages);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the duration of the current period in milliseconds, or {@link #UNKNOWN_TIME} if the
|
|
||||||
* duration is not known.
|
|
||||||
*/
|
|
||||||
long getDuration();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the playback position in the current period, in milliseconds.
|
|
||||||
*/
|
|
||||||
long getCurrentPosition();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the index of the current period.
|
|
||||||
*/
|
|
||||||
int getCurrentPeriodIndex();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current {@link Timeline}, or {@code null} if there is no timeline.
|
* Returns the current {@link Timeline}, or {@code null} if there is no timeline.
|
||||||
*/
|
*/
|
||||||
|
|
@ -361,16 +371,71 @@ public interface ExoPlayer {
|
||||||
*/
|
*/
|
||||||
Object getCurrentManifest();
|
Object getCurrentManifest();
|
||||||
|
|
||||||
/**
|
// Period based.
|
||||||
* Returns an estimate of the absolute position in milliseconds up to which data is buffered,
|
|
||||||
* or {@link #UNKNOWN_TIME} if no estimate is available.
|
|
||||||
*/
|
|
||||||
long getBufferedPosition();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an estimate of the percentage into the media up to which data is buffered, or 0 if no
|
* Returns the index of the current period.
|
||||||
* estimate is available.
|
|
||||||
*/
|
*/
|
||||||
int getBufferedPercentage();
|
int getCurrentPeriodIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration of the current period in milliseconds, or {@link #UNKNOWN_TIME} if the
|
||||||
|
* duration is not known.
|
||||||
|
*/
|
||||||
|
long getCurrentPeriodDuration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the playback position in the current period, in milliseconds.
|
||||||
|
*/
|
||||||
|
long getCurrentPositionInPeriod();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an estimate of the position in the current period up to which data is buffered, or
|
||||||
|
* {@link #UNKNOWN_TIME} if no estimate is available.
|
||||||
|
*/
|
||||||
|
long getBufferedPositionInPeriod();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an estimate of the percentage in the current period up to which data is buffered, or 0
|
||||||
|
* if no estimate is available.
|
||||||
|
*/
|
||||||
|
int getBufferedPercentageInPeriod();
|
||||||
|
|
||||||
|
// Window based.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the seek window associated with the current period, or -1 if the timeline
|
||||||
|
* is not set.
|
||||||
|
*/
|
||||||
|
int getCurrentWindowIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration of the current window in milliseconds, or {@link #UNKNOWN_TIME} if the
|
||||||
|
* duration is not known.
|
||||||
|
*/
|
||||||
|
long getCurrentWindowDuration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the playback position in the current seek window, in milliseconds, or
|
||||||
|
* {@link #UNKNOWN_TIME} if the timeline is not set.
|
||||||
|
*/
|
||||||
|
long getCurrentPositionInWindow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an estimate of the position in the current window up to which data is buffered, or
|
||||||
|
* {@link #UNKNOWN_TIME} if no estimate is available.
|
||||||
|
*/
|
||||||
|
long getBufferedPositionInWindow();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an estimate of the percentage in the current window up to which data is buffered, or 0
|
||||||
|
* if no estimate is available.
|
||||||
|
*/
|
||||||
|
int getBufferedPercentageInWindow();
|
||||||
|
|
||||||
|
// Misc methods
|
||||||
|
|
||||||
|
// TODO - Add a method/methods to expose this.
|
||||||
|
// getBufferedPosition -> periodIndex,position
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,12 +127,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekTo(long positionMs) {
|
public void seekInCurrentPeriod(long positionMs) {
|
||||||
seekTo(getCurrentPeriodIndex(), positionMs);
|
seekInPeriod(getCurrentPeriodIndex(), positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekTo(int periodIndex, long positionMs) {
|
public void seekToDefaultPositionForPeriod(int periodIndex) {
|
||||||
|
seekInPeriod(periodIndex, UNKNOWN_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekInPeriod(int periodIndex, long positionMs) {
|
||||||
boolean seekToDefaultPosition = positionMs == UNKNOWN_TIME;
|
boolean seekToDefaultPosition = positionMs == UNKNOWN_TIME;
|
||||||
maskingPeriodIndex = periodIndex;
|
maskingPeriodIndex = periodIndex;
|
||||||
maskingPositionMs = seekToDefaultPosition ? 0 : positionMs;
|
maskingPositionMs = seekToDefaultPosition ? 0 : positionMs;
|
||||||
|
|
@ -146,8 +151,41 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekToDefaultPosition(int periodIndex) {
|
public void seekInCurrentWindow(long positionMs) {
|
||||||
seekTo(periodIndex, UNKNOWN_TIME);
|
Timeline timeline = getCurrentTimeline();
|
||||||
|
if (timeline == null) {
|
||||||
|
throw new IllegalArgumentException("Windows are not yet known");
|
||||||
|
}
|
||||||
|
int windowIndex = timeline.getPeriodWindowIndex(getCurrentPeriodIndex());
|
||||||
|
seekInWindow(windowIndex, positionMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekToDefaultPositionForWindow(int windowIndex) {
|
||||||
|
if (timeline == null) {
|
||||||
|
throw new IllegalArgumentException("Windows are not yet known");
|
||||||
|
}
|
||||||
|
Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount());
|
||||||
|
Window window = timeline.getWindow(windowIndex);
|
||||||
|
seekToDefaultPositionForPeriod(window.startPeriodIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekInWindow(int windowIndex, long positionMs) {
|
||||||
|
if (timeline == null) {
|
||||||
|
throw new IllegalArgumentException("Windows are not yet known");
|
||||||
|
}
|
||||||
|
Assertions.checkIndex(windowIndex, 0, timeline.getWindowCount());
|
||||||
|
Window window = timeline.getWindow(windowIndex);
|
||||||
|
int periodIndex = window.startPeriodIndex;
|
||||||
|
long periodPositionMs = window.startTimeMs + positionMs;
|
||||||
|
long periodDurationMs = timeline.getPeriodDurationMs(periodIndex);
|
||||||
|
while (periodDurationMs != UNKNOWN_TIME && periodPositionMs >= periodDurationMs
|
||||||
|
&& periodIndex < window.endPeriodIndex) {
|
||||||
|
periodPositionMs -= periodDurationMs;
|
||||||
|
periodDurationMs = timeline.getPeriodDurationMs(++periodIndex);
|
||||||
|
}
|
||||||
|
seekInPeriod(periodIndex, periodPositionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -172,7 +210,12 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDuration() {
|
public int getCurrentPeriodIndex() {
|
||||||
|
return pendingSeekAcks == 0 ? playbackInfo.periodIndex : maskingPeriodIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPeriodDuration() {
|
||||||
if (timeline == null) {
|
if (timeline == null) {
|
||||||
return UNKNOWN_TIME;
|
return UNKNOWN_TIME;
|
||||||
}
|
}
|
||||||
|
|
@ -180,14 +223,89 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getCurrentPosition() {
|
public long getCurrentPositionInPeriod() {
|
||||||
return pendingSeekAcks > 0 ? maskingPositionMs
|
return pendingSeekAcks > 0 ? maskingPositionMs
|
||||||
: playbackInfo.positionUs == C.UNSET_TIME_US ? 0 : (playbackInfo.positionUs / 1000);
|
: playbackInfo.positionUs == C.UNSET_TIME_US ? 0 : (playbackInfo.positionUs / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCurrentPeriodIndex() {
|
public long getBufferedPositionInPeriod() {
|
||||||
return pendingSeekAcks == 0 ? playbackInfo.periodIndex : maskingPeriodIndex;
|
if (pendingSeekAcks == 0) {
|
||||||
|
long bufferedPositionUs = playbackInfo.bufferedPositionUs;
|
||||||
|
return bufferedPositionUs == C.UNSET_TIME_US ? UNKNOWN_TIME : (bufferedPositionUs / 1000);
|
||||||
|
} else {
|
||||||
|
return maskingPositionMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBufferedPercentageInPeriod() {
|
||||||
|
if (timeline == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
long bufferedPosition = getBufferedPositionInPeriod();
|
||||||
|
long duration = getCurrentPeriodDuration();
|
||||||
|
return bufferedPosition == ExoPlayer.UNKNOWN_TIME || duration == ExoPlayer.UNKNOWN_TIME ? 0
|
||||||
|
: (int) (duration == 0 ? 100 : (bufferedPosition * 100) / duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentWindowIndex() {
|
||||||
|
if (timeline == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return timeline.getPeriodWindowIndex(getCurrentPeriodIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentWindowDuration() {
|
||||||
|
if (timeline == null) {
|
||||||
|
return UNKNOWN_TIME;
|
||||||
|
}
|
||||||
|
return timeline.getWindow(getCurrentWindowIndex()).durationMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPositionInWindow() {
|
||||||
|
if (timeline == null) {
|
||||||
|
return UNKNOWN_TIME;
|
||||||
|
}
|
||||||
|
int periodIndex = getCurrentPeriodIndex();
|
||||||
|
int windowIndex = timeline.getPeriodWindowIndex(periodIndex);
|
||||||
|
Window window = timeline.getWindow(windowIndex);
|
||||||
|
long position = getCurrentPositionInPeriod();
|
||||||
|
for (int i = window.startPeriodIndex; i < periodIndex; i++) {
|
||||||
|
position += timeline.getPeriodDurationMs(i);
|
||||||
|
}
|
||||||
|
position -= window.startTimeMs;
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBufferedPositionInWindow() {
|
||||||
|
// TODO - Implement this properly.
|
||||||
|
if (timeline == null) {
|
||||||
|
return UNKNOWN_TIME;
|
||||||
|
}
|
||||||
|
int periodIndex = getCurrentPeriodIndex();
|
||||||
|
int windowIndex = timeline.getPeriodWindowIndex(periodIndex);
|
||||||
|
Window window = timeline.getWindow(windowIndex);
|
||||||
|
if (window.startPeriodIndex == periodIndex && window.endPeriodIndex == periodIndex
|
||||||
|
&& window.startTimeMs == 0 && window.durationMs == getCurrentPeriodDuration()) {
|
||||||
|
return getBufferedPositionInPeriod();
|
||||||
|
}
|
||||||
|
return getCurrentPositionInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBufferedPercentageInWindow() {
|
||||||
|
if (timeline == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
long bufferedPosition = getBufferedPositionInWindow();
|
||||||
|
long duration = getCurrentWindowDuration();
|
||||||
|
return bufferedPosition == ExoPlayer.UNKNOWN_TIME || duration == ExoPlayer.UNKNOWN_TIME ? 0
|
||||||
|
: (int) (duration == 0 ? 100 : (bufferedPosition * 100) / duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -200,24 +318,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
return manifest;
|
return manifest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getBufferedPosition() {
|
|
||||||
if (pendingSeekAcks == 0) {
|
|
||||||
long bufferedPositionUs = playbackInfo.bufferedPositionUs;
|
|
||||||
return bufferedPositionUs == C.UNSET_TIME_US ? UNKNOWN_TIME : (bufferedPositionUs / 1000);
|
|
||||||
} else {
|
|
||||||
return maskingPositionMs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBufferedPercentage() {
|
|
||||||
long bufferedPosition = getBufferedPosition();
|
|
||||||
long duration = getDuration();
|
|
||||||
return bufferedPosition == UNKNOWN_TIME || duration == UNKNOWN_TIME ? 0
|
|
||||||
: (int) (duration == 0 ? 100 : (bufferedPosition * 100) / duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not private so it can be called from an inner class without going through a thunk method.
|
// Not private so it can be called from an inner class without going through a thunk method.
|
||||||
/* package */ void handleEvent(Message msg) {
|
/* package */ void handleEvent(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
|
|
|
||||||
|
|
@ -344,18 +344,33 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekTo(long positionMs) {
|
public void seekInCurrentPeriod(long positionMs) {
|
||||||
player.seekTo(positionMs);
|
player.seekInCurrentPeriod(positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekTo(int periodIndex, long positionMs) {
|
public void seekToDefaultPositionForPeriod(int periodIndex) {
|
||||||
player.seekTo(periodIndex, positionMs);
|
player.seekToDefaultPositionForPeriod(periodIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekToDefaultPosition(int periodIndex) {
|
public void seekInPeriod(int periodIndex, long positionMs) {
|
||||||
player.seekToDefaultPosition(periodIndex);
|
player.seekInPeriod(periodIndex, positionMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekInCurrentWindow(long positionMs) {
|
||||||
|
player.seekInCurrentWindow(positionMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekToDefaultPositionForWindow(int windowIndex) {
|
||||||
|
player.seekToDefaultPositionForWindow(windowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekInWindow(int windowIndex, long positionMs) {
|
||||||
|
player.seekInWindow(windowIndex, positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -378,21 +393,56 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||||
player.blockingSendMessages(messages);
|
player.blockingSendMessages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDuration() {
|
|
||||||
return player.getDuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getCurrentPosition() {
|
|
||||||
return player.getCurrentPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCurrentPeriodIndex() {
|
public int getCurrentPeriodIndex() {
|
||||||
return player.getCurrentPeriodIndex();
|
return player.getCurrentPeriodIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPeriodDuration() {
|
||||||
|
return player.getCurrentPeriodDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPositionInPeriod() {
|
||||||
|
return player.getCurrentPositionInPeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBufferedPositionInPeriod() {
|
||||||
|
return player.getBufferedPositionInPeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBufferedPercentageInPeriod() {
|
||||||
|
return player.getBufferedPercentageInPeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentWindowIndex() {
|
||||||
|
return player.getCurrentWindowIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentWindowDuration() {
|
||||||
|
return player.getCurrentWindowDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCurrentPositionInWindow() {
|
||||||
|
return player.getCurrentPositionInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBufferedPositionInWindow() {
|
||||||
|
return player.getBufferedPositionInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBufferedPercentageInWindow() {
|
||||||
|
return player.getBufferedPercentageInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Timeline getCurrentTimeline() {
|
public Timeline getCurrentTimeline() {
|
||||||
return player.getCurrentTimeline();
|
return player.getCurrentTimeline();
|
||||||
|
|
@ -403,16 +453,6 @@ public final class SimpleExoPlayer implements ExoPlayer {
|
||||||
return player.getCurrentManifest();
|
return player.getCurrentManifest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getBufferedPosition() {
|
|
||||||
return player.getBufferedPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBufferedPercentage() {
|
|
||||||
return player.getBufferedPercentage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
private void buildRenderers(Context context, DrmSessionManager drmSessionManager,
|
private void buildRenderers(Context context, DrmSessionManager drmSessionManager,
|
||||||
|
|
|
||||||
|
|
@ -48,17 +48,20 @@ public class MediaControllerPrevNextClickListener implements OnClickListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
int currentPeriodIndex = player.getCurrentPeriodIndex();
|
int currentWindowIndex = player.getCurrentWindowIndex();
|
||||||
|
if (currentWindowIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isNext) {
|
if (isNext) {
|
||||||
if (currentPeriodIndex < player.getCurrentTimeline().getPeriodCount() - 1) {
|
if (currentWindowIndex < player.getCurrentTimeline().getWindowCount() - 1) {
|
||||||
player.seekTo(currentPeriodIndex + 1, 0);
|
player.seekToDefaultPositionForWindow(currentWindowIndex + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentPeriodIndex > 0
|
if (currentWindowIndex > 0
|
||||||
&& player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS_PERIOD) {
|
&& player.getCurrentPositionInWindow() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS_PERIOD) {
|
||||||
player.seekTo(currentPeriodIndex - 1, 0);
|
player.seekToDefaultPositionForWindow(currentWindowIndex - 1);
|
||||||
} else {
|
} else {
|
||||||
player.seekTo(currentPeriodIndex, 0);
|
player.seekInWindow(currentWindowIndex, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.ui;
|
||||||
import android.widget.MediaController.MediaPlayerControl;
|
import android.widget.MediaController.MediaPlayerControl;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link MediaPlayerControl} for controlling an {@link ExoPlayer} instance.
|
* An implementation of {@link MediaPlayerControl} for controlling an {@link ExoPlayer} instance.
|
||||||
|
|
@ -65,19 +64,19 @@ public class PlayerControl implements MediaPlayerControl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBufferPercentage() {
|
public int getBufferPercentage() {
|
||||||
return exoPlayer.getBufferedPercentage();
|
return exoPlayer.getBufferedPercentageInWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCurrentPosition() {
|
public int getCurrentPosition() {
|
||||||
return exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
|
long position = exoPlayer.getCurrentPositionInWindow();
|
||||||
: (int) exoPlayer.getCurrentPosition();
|
return position == ExoPlayer.UNKNOWN_TIME ? 0 : (int) position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDuration() {
|
public int getDuration() {
|
||||||
return exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
|
long duration = exoPlayer.getCurrentWindowDuration();
|
||||||
: (int) exoPlayer.getDuration();
|
return duration == ExoPlayer.UNKNOWN_TIME ? 0 : (int) duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -97,9 +96,11 @@ public class PlayerControl implements MediaPlayerControl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seekTo(int timeMillis) {
|
public void seekTo(int timeMillis) {
|
||||||
long seekPosition = exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
|
int windowIndex = exoPlayer.getCurrentWindowIndex();
|
||||||
: Util.constrainValue(timeMillis, 0, getDuration());
|
if (windowIndex == -1) {
|
||||||
exoPlayer.seekTo(seekPosition);
|
return;
|
||||||
|
}
|
||||||
|
exoPlayer.seekInWindow(windowIndex, timeMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public abstract class Action {
|
||||||
protected abstract void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector);
|
protected abstract void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@link ExoPlayer#seekTo(long)}.
|
* Calls {@link ExoPlayer#seekInCurrentPeriod(long)}.
|
||||||
*/
|
*/
|
||||||
public static final class Seek extends Action {
|
public static final class Seek extends Action {
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ public abstract class Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) {
|
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) {
|
||||||
player.seekTo(positionMs);
|
player.seekInCurrentPeriod(positionMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
||||||
@Override
|
@Override
|
||||||
public final void onStop() {
|
public final void onStop() {
|
||||||
actionHandler.removeCallbacksAndMessages(null);
|
actionHandler.removeCallbacksAndMessages(null);
|
||||||
sourceDurationMs = player.getDuration();
|
sourceDurationMs = player.getCurrentPeriodDuration();
|
||||||
player.release();
|
player.release();
|
||||||
player = null;
|
player = null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue