Commit 2073f3fc by andrewlewis Committed by Oliver Woodman

Expose source indices via ExoPlayer (playlists #5).

ExoPlayer.EventListener.onPositionDiscontinuity is notified during seeking and
transitioning from one source to the next.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=125578976
parent f9fa54cd
......@@ -73,6 +73,11 @@ public class EventLogger implements ExoPlayer.EventListener, SimpleExoPlayer.Deb
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
Log.d(TAG, "discontinuity [" + sourceIndex + ", " + positionMs + "]");
}
@Override
public void onPlayWhenReadyCommitted() {
// Do nothing.
}
......
......@@ -392,6 +392,14 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
if (mediaController.isShowing()) {
// The MediaController is visible, so force it to show the updated position immediately.
mediaController.show();
}
}
@Override
public void onPlayerError(ExoPlaybackException e) {
String errorString = null;
if (e.type == ExoPlaybackException.TYPE_RENDERER) {
......
......@@ -93,6 +93,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
playbackException = error;
}
......
......@@ -93,6 +93,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
playbackException = error;
}
......
......@@ -112,6 +112,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
// Do nothing.
}
@Override
public void onPlayerError(ExoPlaybackException error) {
playbackException = error;
}
......
......@@ -118,6 +118,16 @@ public interface ExoPlayer {
*/
void onPlayWhenReadyCommitted();
// TODO[playlists]: Should source-initiated resets also cause this to be invoked?
/**
* Invoked when the player's position changes due to a discontinuity (seeking or playback
* transitioning to the next source).
*
* @param sourceIndex The index of the source being played.
* @param positionMs The playback position in that source, in milliseconds.
*/
void onPositionDiscontinuity(int sourceIndex, long positionMs);
/**
* Invoked when an error occurs. The playback state will transition to
* {@link ExoPlayer#STATE_IDLE} immediately after this method is invoked. The player instance
......@@ -227,8 +237,9 @@ public interface ExoPlayer {
void setSource(SampleSource sampleSource);
/**
* Sets the player's source provider. The player will transition to {@link #STATE_BUFFERING} until
* it is ready to play the first source.
* Sets the player's source provider. The player's position will be reset to the start of the
* first source and the player will transition to {@link #STATE_BUFFERING} until it is ready to
* play it.
*
* @param sourceProvider The provider of {@link SampleSource}s to play.
*/
......@@ -259,13 +270,21 @@ public interface ExoPlayer {
boolean isPlayWhenReadyCommitted();
/**
* Seeks to a position specified in milliseconds.
* Seeks to a position specified in milliseconds in the current source.
*
* @param positionMs The seek position.
*/
void seekTo(long positionMs);
/**
* Seeks to a position specified in milliseconds in the specified source.
*
* @param sourceIndex The index of the source to seek to.
* @param positionMs The seek position relative to the start of the specified source.
*/
void seekTo(int sourceIndex, long positionMs);
/**
* Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention
* is to pause playback.
* <p>
......@@ -312,13 +331,20 @@ public interface ExoPlayer {
long getDuration();
/**
* Gets the current playback position in milliseconds.
* Gets the playback position in the current source, in milliseconds.
*
* @return The current playback position in milliseconds.
* @return The playback position in the current source, in milliseconds.
*/
long getCurrentPosition();
/**
* Gets the index of the current source.
*
* @return The index of the current source.
*/
int getCurrentSourceIndex();
/**
* Gets an estimate of the absolute position in milliseconds up to which data is buffered.
*
* @return An estimate of the absolute position in milliseconds up to which data is buffered,
......
......@@ -39,6 +39,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
private boolean playWhenReady;
private int playbackState;
private int pendingPlayWhenReadyAcks;
private int pendingSetSourceProviderAndSeekAcks;
// Playback information when there is no pending seek/set source operation.
private ExoPlayerImplInternal.PlaybackInfo playbackInfo;
// Playback information when there is a pending seek/set source operation.
private int sourceIndex;
private long position;
private long duration;
/**
* Constructs an instance. Must be invoked from a thread that has an associated {@link Looper}.
......@@ -68,6 +77,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
};
internalPlayer = new ExoPlayerImplInternal(renderers, trackSelector, minBufferMs, minRebufferMs,
playWhenReady, eventHandler);
playbackInfo = new ExoPlayerImplInternal.PlaybackInfo(0);
}
@Override
......@@ -87,12 +97,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public void setSource(final SampleSource sampleSource) {
internalPlayer.setSourceProvider(new SingleSampleSourceProvider(sampleSource));
setSourceProvider(new SingleSampleSourceProvider(sampleSource));
}
@Override
public void setSourceProvider(SampleSourceProvider sourceProvider) {
duration = ExoPlayer.UNKNOWN_TIME;
position = 0;
sourceIndex = 0;
pendingSetSourceProviderAndSeekAcks++;
internalPlayer.setSourceProvider(sourceProvider);
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(sourceIndex, position);
}
}
@Override
......@@ -119,7 +137,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public void seekTo(long positionMs) {
internalPlayer.seekTo(positionMs);
seekTo(getCurrentSourceIndex(), positionMs);
}
@Override
public void seekTo(int sourceIndex, long positionMs) {
duration = sourceIndex == getCurrentSourceIndex() ? getDuration() : ExoPlayer.UNKNOWN_TIME;
position = positionMs;
this.sourceIndex = sourceIndex;
pendingSetSourceProviderAndSeekAcks++;
internalPlayer.seekTo(sourceIndex, position);
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(sourceIndex, position);
}
}
@Override
......@@ -145,17 +176,33 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Override
public long getDuration() {
return internalPlayer.getDuration();
if (pendingSetSourceProviderAndSeekAcks == 0) {
long durationUs = playbackInfo.durationUs;
return durationUs == C.UNSET_TIME_US ? ExoPlayer.UNKNOWN_TIME : durationUs / 1000;
} else {
return duration;
}
}
@Override
public long getCurrentPosition() {
return internalPlayer.getCurrentPosition();
return pendingSetSourceProviderAndSeekAcks == 0 ? playbackInfo.positionUs / 1000 : position;
}
@Override
public int getCurrentSourceIndex() {
return pendingSetSourceProviderAndSeekAcks == 0 ? playbackInfo.sourceIndex : sourceIndex;
}
@Override
public long getBufferedPosition() {
return internalPlayer.getBufferedPosition();
if (pendingSetSourceProviderAndSeekAcks == 0) {
long bufferedPositionUs = playbackInfo.bufferedPositionUs;
return bufferedPositionUs == C.UNSET_TIME_US || bufferedPositionUs == C.END_OF_SOURCE_US
? ExoPlayer.UNKNOWN_TIME : bufferedPositionUs / 1000;
} else {
return position;
}
}
@Override
......@@ -185,6 +232,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
break;
}
case ExoPlayerImplInternal.MSG_SET_SOURCE_PROVIDER_ACK: // Fall through.
case ExoPlayerImplInternal.MSG_SEEK_ACK: {
pendingSetSourceProviderAndSeekAcks--;
break;
}
case ExoPlayerImplInternal.MSG_SOURCE_CHANGED: {
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
if (pendingSetSourceProviderAndSeekAcks == 0) {
for (EventListener listener : listeners) {
listener.onPositionDiscontinuity(playbackInfo.sourceIndex, 0);
}
}
break;
}
case ExoPlayerImplInternal.MSG_ERROR: {
ExoPlaybackException exception = (ExoPlaybackException) msg.obj;
for (EventListener listener : listeners) {
......
......@@ -344,6 +344,11 @@ public final class SimpleExoPlayer implements ExoPlayer {
}
@Override
public void seekTo(int sourceIndex, long positionMs) {
player.seekTo(sourceIndex, positionMs);
}
@Override
public void stop() {
player.stop();
}
......@@ -374,6 +379,11 @@ public final class SimpleExoPlayer implements ExoPlayer {
}
@Override
public int getCurrentSourceIndex() {
return player.getCurrentSourceIndex();
}
@Override
public long getBufferedPosition() {
return player.getBufferedPosition();
}
......
......@@ -81,11 +81,11 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
}
private void updateTextView() {
textView.setText(getPlayerStateString() + getBandwidthString() + getVideoString()
+ getAudioString());
textView.setText(getPlayerStateString() + getPlayerSourceIndexString() + getBandwidthString()
+ getVideoString() + getAudioString());
}
public String getPlayerStateString() {
private String getPlayerStateString() {
String text = "playWhenReady:" + player.getPlayWhenReady() + " playbackState:";
switch(player.getPlaybackState()) {
case ExoPlayer.STATE_BUFFERING:
......@@ -107,6 +107,10 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
return text;
}
private String getPlayerSourceIndexString() {
return " source:" + player.getCurrentSourceIndex();
}
private String getBandwidthString() {
BandwidthMeter bandwidthMeter = player.getBandwidthMeter();
if (bandwidthMeter == null
......@@ -160,6 +164,11 @@ public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListe
}
@Override
public void onPositionDiscontinuity(int sourceIndex, long positionMs) {
updateTextView();
}
@Override
public void onPlayerError(ExoPlaybackException error) {
// Do nothing.
}
......
......@@ -204,6 +204,11 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
// Do nothing.
}
@Override
public final void onPositionDiscontinuity(int sourceIndex, long positionMs) {
// Do nothing.
}
// SimpleExoPlayer.DebugListener
@Override
......
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