Commit 30cfc3c6 by tonihei

Merge branch 'dev-v2' of https://github.com/google/ExoPlayer into dev-v2

parents 42ec358c 623be98d
Showing with 279 additions and 252 deletions
......@@ -85,6 +85,10 @@
* RTMP extension:
* Upgrade to `io.antmedia:rtmp_client`, which does not rely on `jcenter()`
([#9591](https://github.com/google/ExoPlayer/issues/9591)).
* MediaSession extension:
* Rename
`MediaSessionConnector.QueueNavigator#onCurrentWindowIndexChanged` to
`onCurrentMediaItemIndexChanged`.
* Remove deprecated symbols:
* Remove `Renderer.VIDEO_SCALING_MODE_*` constants. Use identically named
constants in `C` instead.
......
......@@ -261,7 +261,7 @@ import java.util.ArrayList;
int playbackState = currentPlayer.getPlaybackState();
maybeSetCurrentItemAndNotify(
playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED
? currentPlayer.getCurrentWindowIndex()
? currentPlayer.getCurrentMediaItemIndex()
: C.INDEX_UNSET);
}
......@@ -281,7 +281,7 @@ import java.util.ArrayList;
// Player state management.
long playbackPositionMs = C.TIME_UNSET;
int windowIndex = C.INDEX_UNSET;
int currentItemIndex = C.INDEX_UNSET;
boolean playWhenReady = false;
Player previousPlayer = this.currentPlayer;
......@@ -291,10 +291,10 @@ import java.util.ArrayList;
if (playbackState != Player.STATE_ENDED) {
playbackPositionMs = previousPlayer.getCurrentPosition();
playWhenReady = previousPlayer.getPlayWhenReady();
windowIndex = previousPlayer.getCurrentWindowIndex();
if (windowIndex != currentItemIndex) {
currentItemIndex = previousPlayer.getCurrentMediaItemIndex();
if (currentItemIndex != this.currentItemIndex) {
playbackPositionMs = C.TIME_UNSET;
windowIndex = currentItemIndex;
currentItemIndex = this.currentItemIndex;
}
}
previousPlayer.stop();
......@@ -304,7 +304,7 @@ import java.util.ArrayList;
this.currentPlayer = currentPlayer;
// Media queue management.
currentPlayer.setMediaItems(mediaQueue, windowIndex, playbackPositionMs);
currentPlayer.setMediaItems(mediaQueue, currentItemIndex, playbackPositionMs);
currentPlayer.setPlayWhenReady(playWhenReady);
currentPlayer.prepare();
}
......
......@@ -65,7 +65,7 @@ public class PlayerActivity extends AppCompatActivity
// Saved instance state keys.
private static final String KEY_TRACK_SELECTION_PARAMETERS = "track_selection_parameters";
private static final String KEY_WINDOW = "window";
private static final String KEY_ITEM_INDEX = "item_index";
private static final String KEY_POSITION = "position";
private static final String KEY_AUTO_PLAY = "auto_play";
......@@ -83,7 +83,7 @@ public class PlayerActivity extends AppCompatActivity
private DebugTextViewHelper debugViewHelper;
private TracksInfo lastSeenTracksInfo;
private boolean startAutoPlay;
private int startWindow;
private int startItemIndex;
private long startPosition;
// For ad playback only.
......@@ -114,7 +114,7 @@ public class PlayerActivity extends AppCompatActivity
DefaultTrackSelector.Parameters.CREATOR.fromBundle(
savedInstanceState.getBundle(KEY_TRACK_SELECTION_PARAMETERS));
startAutoPlay = savedInstanceState.getBoolean(KEY_AUTO_PLAY);
startWindow = savedInstanceState.getInt(KEY_WINDOW);
startItemIndex = savedInstanceState.getInt(KEY_ITEM_INDEX);
startPosition = savedInstanceState.getLong(KEY_POSITION);
} else {
trackSelectionParameters =
......@@ -206,7 +206,7 @@ public class PlayerActivity extends AppCompatActivity
updateStartPosition();
outState.putBundle(KEY_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
outState.putBoolean(KEY_AUTO_PLAY, startAutoPlay);
outState.putInt(KEY_WINDOW, startWindow);
outState.putInt(KEY_ITEM_INDEX, startItemIndex);
outState.putLong(KEY_POSITION, startPosition);
}
......@@ -282,9 +282,9 @@ public class PlayerActivity extends AppCompatActivity
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
debugViewHelper.start();
}
boolean haveStartPosition = startWindow != C.INDEX_UNSET;
boolean haveStartPosition = startItemIndex != C.INDEX_UNSET;
if (haveStartPosition) {
player.seekTo(startWindow, startPosition);
player.seekTo(startItemIndex, startPosition);
}
player.setMediaItems(mediaItems, /* resetPosition= */ !haveStartPosition);
player.prepare();
......@@ -382,14 +382,14 @@ public class PlayerActivity extends AppCompatActivity
private void updateStartPosition() {
if (player != null) {
startAutoPlay = player.getPlayWhenReady();
startWindow = player.getCurrentWindowIndex();
startItemIndex = player.getCurrentMediaItemIndex();
startPosition = Math.max(0, player.getContentPosition());
}
}
protected void clearStartPosition() {
startAutoPlay = true;
startWindow = C.INDEX_UNSET;
startItemIndex = C.INDEX_UNSET;
startPosition = C.TIME_UNSET;
}
......
......@@ -318,9 +318,9 @@ public final class CastPlayer extends BasePlayer {
@Override
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
int windowIndex = resetPosition ? 0 : getCurrentWindowIndex();
int mediaItemIndex = resetPosition ? 0 : getCurrentMediaItemIndex();
long startPositionMs = resetPosition ? C.TIME_UNSET : getContentPosition();
setMediaItems(mediaItems, windowIndex, startPositionMs);
setMediaItems(mediaItems, mediaItemIndex, startPositionMs);
}
@Override
......@@ -443,7 +443,7 @@ public final class CastPlayer extends BasePlayer {
// in RemoteMediaClient.
positionMs = positionMs != C.TIME_UNSET ? positionMs : 0;
if (mediaStatus != null) {
if (getCurrentWindowIndex() != mediaItemIndex) {
if (getCurrentMediaItemIndex() != mediaItemIndex) {
remoteMediaClient
.queueJumpToItem(
(int) currentTimeline.getPeriod(mediaItemIndex, period).uid, positionMs, null)
......@@ -636,7 +636,7 @@ public final class CastPlayer extends BasePlayer {
@Override
public int getCurrentPeriodIndex() {
return getCurrentWindowIndex();
return getCurrentMediaItemIndex();
}
@Override
......@@ -1103,15 +1103,15 @@ public final class CastPlayer extends BasePlayer {
@Nullable
private PendingResult<MediaChannelResult> setMediaItemsInternal(
MediaQueueItem[] mediaQueueItems,
int startWindowIndex,
int startIndex,
long startPositionMs,
@RepeatMode int repeatMode) {
if (remoteMediaClient == null || mediaQueueItems.length == 0) {
return null;
}
startPositionMs = startPositionMs == C.TIME_UNSET ? 0 : startPositionMs;
if (startWindowIndex == C.INDEX_UNSET) {
startWindowIndex = getCurrentWindowIndex();
if (startIndex == C.INDEX_UNSET) {
startIndex = getCurrentMediaItemIndex();
startPositionMs = getCurrentPosition();
}
Timeline currentTimeline = getCurrentTimeline();
......@@ -1120,7 +1120,7 @@ public final class CastPlayer extends BasePlayer {
}
return remoteMediaClient.queueLoad(
mediaQueueItems,
min(startWindowIndex, mediaQueueItems.length - 1),
min(startIndex, mediaQueueItems.length - 1),
getCastRepeatMode(repeatMode),
startPositionMs,
/* customData= */ null);
......@@ -1180,7 +1180,7 @@ public final class CastPlayer extends BasePlayer {
}
return new PositionInfo(
newWindowUid,
getCurrentWindowIndex(),
getCurrentMediaItemIndex(),
newMediaItem,
newPeriodUid,
getCurrentPeriodIndex(),
......
......@@ -279,7 +279,7 @@ import com.google.android.exoplayer2.util.Util;
timeline.getPeriod(0, period).getAdDurationUs(adGroupIndex, adIndexInAdGroup);
return Util.usToMs(adDurationUs);
} else {
return timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
return timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
}
}
......
......@@ -141,7 +141,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
if (player.getPlaybackState() == Player.STATE_IDLE) {
player.prepare();
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
player.seekToDefaultPosition(player.getCurrentWindowIndex());
player.seekToDefaultPosition(player.getCurrentMediaItemIndex());
}
if (player.isCommandAvailable(Player.COMMAND_PLAY_PAUSE)) {
player.play();
......
......@@ -253,8 +253,8 @@ import java.util.List;
// checkIndex() throws IndexOutOfBoundsException which maps the RESULT_ERROR_BAD_VALUE
// but RESULT_ERROR_INVALID_STATE with IllegalStateException is expected here.
Assertions.checkState(0 <= index && index < timeline.getWindowCount());
int windowIndex = player.getCurrentWindowIndex();
if (windowIndex == index || !player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)) {
int currentIndex = player.getCurrentMediaItemIndex();
if (currentIndex == index || !player.isCommandAvailable(COMMAND_SEEK_TO_MEDIA_ITEM)) {
return false;
}
player.seekToDefaultPosition(index);
......@@ -301,7 +301,7 @@ import java.util.List;
}
public int getCurrentMediaItemIndex() {
return media2Playlist.isEmpty() ? C.INDEX_UNSET : player.getCurrentWindowIndex();
return media2Playlist.isEmpty() ? C.INDEX_UNSET : player.getCurrentMediaItemIndex();
}
public int getPreviousMediaItemIndex() {
......@@ -331,7 +331,7 @@ import java.util.List;
if (!player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)) {
return false;
}
player.seekTo(player.getCurrentWindowIndex(), /* positionMs= */ 0);
player.seekTo(player.getCurrentMediaItemIndex(), /* positionMs= */ 0);
}
boolean playWhenReady = player.getPlayWhenReady();
int suppressReason = player.getPlaybackSuppressionReason();
......@@ -358,7 +358,7 @@ import java.util.List;
if (!player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)) {
return false;
}
player.seekTo(player.getCurrentWindowIndex(), position);
player.seekTo(player.getCurrentMediaItemIndex(), position);
return true;
}
......@@ -493,7 +493,7 @@ import java.util.List;
public boolean isCurrentMediaItemSeekable() {
return getCurrentMediaItem() != null
&& !player.isPlayingAd()
&& player.isCurrentWindowSeekable();
&& player.isCurrentMediaItemSeekable();
}
public boolean canSkipToPlaylistItem() {
......@@ -502,11 +502,11 @@ import java.util.List;
}
public boolean canSkipToPreviousPlaylistItem() {
return player.hasPreviousWindow();
return player.hasPreviousMediaItem();
}
public boolean canSkipToNextPlaylistItem() {
return player.hasNextWindow();
return player.hasNextMediaItem();
}
public boolean hasError() {
......
......@@ -263,12 +263,13 @@ public final class MediaSessionConnector {
* @param player The player connected to the media session.
*/
void onTimelineChanged(Player player);
/**
* Called when the current window index changed.
* Called when the current media item index changed.
*
* @param player The player connected to the media session.
*/
void onCurrentWindowIndexChanged(Player player);
default void onCurrentMediaItemIndexChanged(Player player) {}
/**
* Gets the id of the currently active queue item, or {@link
* MediaSessionCompat.QueueItem#UNKNOWN_ID} if the active item is unknown.
......@@ -969,8 +970,8 @@ public final class MediaSessionConnector {
return player != null && mediaButtonEventHandler != null;
}
private void seekTo(Player player, int windowIndex, long positionMs) {
player.seekTo(windowIndex, positionMs);
private void seekTo(Player player, int mediaItemIndex, long positionMs) {
player.seekTo(mediaItemIndex, positionMs);
}
private static int getMediaSessionPlaybackState(
......@@ -1023,7 +1024,7 @@ public final class MediaSessionConnector {
}
builder.putLong(
MediaMetadataCompat.METADATA_KEY_DURATION,
player.isCurrentWindowDynamic() || player.getDuration() == C.TIME_UNSET
player.isCurrentMediaItemDynamic() || player.getDuration() == C.TIME_UNSET
? -1
: player.getDuration());
long activeQueueItemId = mediaController.getPlaybackState().getActiveQueueItemId();
......@@ -1097,7 +1098,7 @@ public final class MediaSessionConnector {
private class ComponentListener extends MediaSessionCompat.Callback implements Player.Listener {
private int currentWindowIndex;
private int currentMediaItemIndex;
private int currentWindowCount;
// Player.Listener implementation.
......@@ -1107,9 +1108,9 @@ public final class MediaSessionConnector {
boolean invalidatePlaybackState = false;
boolean invalidateMetadata = false;
if (events.contains(Player.EVENT_POSITION_DISCONTINUITY)) {
if (currentWindowIndex != player.getCurrentWindowIndex()) {
if (currentMediaItemIndex != player.getCurrentMediaItemIndex()) {
if (queueNavigator != null) {
queueNavigator.onCurrentWindowIndexChanged(player);
queueNavigator.onCurrentMediaItemIndexChanged(player);
}
invalidateMetadata = true;
}
......@@ -1118,11 +1119,11 @@ public final class MediaSessionConnector {
if (events.contains(Player.EVENT_TIMELINE_CHANGED)) {
int windowCount = player.getCurrentTimeline().getWindowCount();
int windowIndex = player.getCurrentWindowIndex();
int mediaItemIndex = player.getCurrentMediaItemIndex();
if (queueNavigator != null) {
queueNavigator.onTimelineChanged(player);
invalidatePlaybackState = true;
} else if (currentWindowCount != windowCount || currentWindowIndex != windowIndex) {
} else if (currentWindowCount != windowCount || currentMediaItemIndex != mediaItemIndex) {
// active queue item and queue navigation actions may need to be updated
invalidatePlaybackState = true;
}
......@@ -1130,8 +1131,8 @@ public final class MediaSessionConnector {
invalidateMetadata = true;
}
// Update currentWindowIndex after comparisons above.
currentWindowIndex = player.getCurrentWindowIndex();
// Update currentMediaItemIndex after comparisons above.
currentMediaItemIndex = player.getCurrentMediaItemIndex();
if (events.containsAny(
EVENT_PLAYBACK_STATE_CHANGED,
......@@ -1170,7 +1171,7 @@ public final class MediaSessionConnector {
player.prepare();
}
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET);
}
Assertions.checkNotNull(player).play();
}
......@@ -1186,7 +1187,7 @@ public final class MediaSessionConnector {
@Override
public void onSeekTo(long positionMs) {
if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_SEEK_TO)) {
seekTo(player, player.getCurrentWindowIndex(), positionMs);
seekTo(player, player.getCurrentMediaItemIndex(), positionMs);
}
}
......
......@@ -98,7 +98,7 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
boolean enableNext = false;
Timeline timeline = player.getCurrentTimeline();
if (!timeline.isEmpty() && !player.isPlayingAd()) {
timeline.getWindow(player.getCurrentWindowIndex(), window);
timeline.getWindow(player.getCurrentMediaItemIndex(), window);
enableSkipTo = timeline.getWindowCount() > 1;
enablePrevious =
player.isCommandAvailable(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM)
......@@ -128,12 +128,12 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
}
@Override
public final void onCurrentWindowIndexChanged(Player player) {
public final void onCurrentMediaItemIndexChanged(Player player) {
if (activeQueueItemId == MediaSessionCompat.QueueItem.UNKNOWN_ID
|| player.getCurrentTimeline().getWindowCount() > maxQueueSize) {
publishFloatingQueueWindow(player);
} else if (!player.getCurrentTimeline().isEmpty()) {
activeQueueItemId = player.getCurrentWindowIndex();
activeQueueItemId = player.getCurrentMediaItemIndex();
}
}
......@@ -185,40 +185,40 @@ public abstract class TimelineQueueNavigator implements MediaSessionConnector.Qu
int queueSize = min(maxQueueSize, timeline.getWindowCount());
// Add the active queue item.
int currentWindowIndex = player.getCurrentWindowIndex();
int currentMediaItemIndex = player.getCurrentMediaItemIndex();
queue.add(
new MediaSessionCompat.QueueItem(
getMediaDescription(player, currentWindowIndex), currentWindowIndex));
getMediaDescription(player, currentMediaItemIndex), currentMediaItemIndex));
// Fill queue alternating with next and/or previous queue items.
int firstWindowIndex = currentWindowIndex;
int lastWindowIndex = currentWindowIndex;
int firstMediaItemIndex = currentMediaItemIndex;
int lastMediaItemIndex = currentMediaItemIndex;
boolean shuffleModeEnabled = player.getShuffleModeEnabled();
while ((firstWindowIndex != C.INDEX_UNSET || lastWindowIndex != C.INDEX_UNSET)
while ((firstMediaItemIndex != C.INDEX_UNSET || lastMediaItemIndex != C.INDEX_UNSET)
&& queue.size() < queueSize) {
// Begin with next to have a longer tail than head if an even sized queue needs to be trimmed.
if (lastWindowIndex != C.INDEX_UNSET) {
lastWindowIndex =
if (lastMediaItemIndex != C.INDEX_UNSET) {
lastMediaItemIndex =
timeline.getNextWindowIndex(
lastWindowIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
if (lastWindowIndex != C.INDEX_UNSET) {
lastMediaItemIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
if (lastMediaItemIndex != C.INDEX_UNSET) {
queue.add(
new MediaSessionCompat.QueueItem(
getMediaDescription(player, lastWindowIndex), lastWindowIndex));
getMediaDescription(player, lastMediaItemIndex), lastMediaItemIndex));
}
}
if (firstWindowIndex != C.INDEX_UNSET && queue.size() < queueSize) {
firstWindowIndex =
if (firstMediaItemIndex != C.INDEX_UNSET && queue.size() < queueSize) {
firstMediaItemIndex =
timeline.getPreviousWindowIndex(
firstWindowIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
if (firstWindowIndex != C.INDEX_UNSET) {
firstMediaItemIndex, Player.REPEAT_MODE_OFF, shuffleModeEnabled);
if (firstMediaItemIndex != C.INDEX_UNSET) {
queue.addFirst(
new MediaSessionCompat.QueueItem(
getMediaDescription(player, firstWindowIndex), firstWindowIndex));
getMediaDescription(player, firstMediaItemIndex), firstMediaItemIndex));
}
}
}
mediaSession.setQueue(new ArrayList<>(queue));
activeQueueItemId = currentWindowIndex;
activeQueueItemId = currentMediaItemIndex;
}
}
......@@ -118,7 +118,7 @@ public abstract class BasePlayer implements Player {
@Override
public final void seekToDefaultPosition() {
seekToDefaultPosition(getCurrentWindowIndex());
seekToDefaultPosition(getCurrentMediaItemIndex());
}
@Override
......@@ -128,7 +128,7 @@ public abstract class BasePlayer implements Player {
@Override
public final void seekTo(long positionMs) {
seekTo(getCurrentWindowIndex(), positionMs);
seekTo(getCurrentMediaItemIndex(), positionMs);
}
@Override
......@@ -184,13 +184,13 @@ public abstract class BasePlayer implements Player {
if (timeline.isEmpty() || isPlayingAd()) {
return;
}
boolean hasPreviousWindow = hasPreviousWindow();
if (isCurrentWindowLive() && !isCurrentWindowSeekable()) {
if (hasPreviousWindow) {
seekToPreviousWindow();
boolean hasPreviousMediaItem = hasPreviousMediaItem();
if (isCurrentMediaItemLive() && !isCurrentMediaItemSeekable()) {
if (hasPreviousMediaItem) {
seekToPreviousMediaItem();
}
} else if (hasPreviousWindow && getCurrentPosition() <= getMaxSeekToPreviousPosition()) {
seekToPreviousWindow();
} else if (hasPreviousMediaItem && getCurrentPosition() <= getMaxSeekToPreviousPosition()) {
seekToPreviousMediaItem();
} else {
seekTo(/* positionMs= */ 0);
}
......@@ -239,9 +239,9 @@ public abstract class BasePlayer implements Player {
if (timeline.isEmpty() || isPlayingAd()) {
return;
}
if (hasNextWindow()) {
seekToNextWindow();
} else if (isCurrentWindowLive() && isCurrentWindowDynamic()) {
if (hasNextMediaItem()) {
seekToNextMediaItem();
} else if (isCurrentMediaItemLive() && isCurrentMediaItemDynamic()) {
seekToDefaultPosition();
}
}
......@@ -293,7 +293,7 @@ public abstract class BasePlayer implements Player {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty()
? null
: timeline.getWindow(getCurrentWindowIndex(), window).mediaItem;
: timeline.getWindow(getCurrentMediaItemIndex(), window).mediaItem;
}
@Override
......@@ -310,7 +310,9 @@ public abstract class BasePlayer implements Player {
@Nullable
public final Object getCurrentManifest() {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty() ? null : timeline.getWindow(getCurrentWindowIndex(), window).manifest;
return timeline.isEmpty()
? null
: timeline.getWindow(getCurrentMediaItemIndex(), window).manifest;
}
@Override
......@@ -352,7 +354,8 @@ public abstract class BasePlayer implements Player {
if (timeline.isEmpty()) {
return C.TIME_UNSET;
}
long windowStartTimeMs = timeline.getWindow(getCurrentWindowIndex(), window).windowStartTimeMs;
long windowStartTimeMs =
timeline.getWindow(getCurrentMediaItemIndex(), window).windowStartTimeMs;
if (windowStartTimeMs == C.TIME_UNSET) {
return C.TIME_UNSET;
}
......@@ -376,7 +379,7 @@ public abstract class BasePlayer implements Player {
Timeline timeline = getCurrentTimeline();
return timeline.isEmpty()
? C.TIME_UNSET
: timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
: timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
}
/**
......@@ -389,22 +392,24 @@ public abstract class BasePlayer implements Player {
return new Commands.Builder()
.addAll(permanentAvailableCommands)
.addIf(COMMAND_SEEK_TO_DEFAULT_POSITION, !isPlayingAd())
.addIf(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, isCurrentWindowSeekable() && !isPlayingAd())
.addIf(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, hasPreviousWindow() && !isPlayingAd())
.addIf(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, isCurrentMediaItemSeekable() && !isPlayingAd())
.addIf(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, hasPreviousMediaItem() && !isPlayingAd())
.addIf(
COMMAND_SEEK_TO_PREVIOUS,
!getCurrentTimeline().isEmpty()
&& (hasPreviousWindow() || !isCurrentWindowLive() || isCurrentWindowSeekable())
&& (hasPreviousMediaItem()
|| !isCurrentMediaItemLive()
|| isCurrentMediaItemSeekable())
&& !isPlayingAd())
.addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNextWindow() && !isPlayingAd())
.addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNextMediaItem() && !isPlayingAd())
.addIf(
COMMAND_SEEK_TO_NEXT,
!getCurrentTimeline().isEmpty()
&& (hasNextWindow() || (isCurrentWindowLive() && isCurrentWindowDynamic()))
&& (hasNextMediaItem() || (isCurrentMediaItemLive() && isCurrentMediaItemDynamic()))
&& !isPlayingAd())
.addIf(COMMAND_SEEK_TO_MEDIA_ITEM, !isPlayingAd())
.addIf(COMMAND_SEEK_BACK, isCurrentWindowSeekable() && !isPlayingAd())
.addIf(COMMAND_SEEK_FORWARD, isCurrentWindowSeekable() && !isPlayingAd())
.addIf(COMMAND_SEEK_BACK, isCurrentMediaItemSeekable() && !isPlayingAd())
.addIf(COMMAND_SEEK_FORWARD, isCurrentMediaItemSeekable() && !isPlayingAd())
.build();
}
......
......@@ -1126,7 +1126,7 @@ public interface ExoPlayer extends Player {
* @param mediaSources The new {@link MediaSource MediaSources}.
* @param resetPosition Whether the playback position should be reset to the default position in
* the first {@link Timeline.Window}. If false, playback will start from the position defined
* by {@link #getCurrentWindowIndex()} and {@link #getCurrentPosition()}.
* by {@link #getCurrentMediaItemIndex()} and {@link #getCurrentPosition()}.
*/
void setMediaSources(List<MediaSource> mediaSources, boolean resetPosition);
......@@ -1134,14 +1134,15 @@ public interface ExoPlayer extends Player {
* Clears the playlist and adds the specified {@link MediaSource MediaSources}.
*
* @param mediaSources The new {@link MediaSource MediaSources}.
* @param startWindowIndex The window index to start playback from. If {@link C#INDEX_UNSET} is
* passed, the current position is not reset.
* @param startMediaItemIndex The media item index to start playback from. If {@link
* C#INDEX_UNSET} is passed, the current position is not reset.
* @param startPositionMs The position in milliseconds to start playback from. If {@link
* C#TIME_UNSET} is passed, the default position of the given window is used. In any case, if
* {@code startWindowIndex} is set to {@link C#INDEX_UNSET}, this parameter is ignored and the
* position is not reset at all.
* C#TIME_UNSET} is passed, the default position of the given media item is used. In any case,
* if {@code startMediaItemIndex} is set to {@link C#INDEX_UNSET}, this parameter is ignored
* and the position is not reset at all.
*/
void setMediaSources(List<MediaSource> mediaSources, int startWindowIndex, long startPositionMs);
void setMediaSources(
List<MediaSource> mediaSources, int startMediaItemIndex, long startPositionMs);
/**
* Clears the playlist, adds the specified {@link MediaSource} and resets the position to the
......@@ -1164,7 +1165,7 @@ public interface ExoPlayer extends Player {
*
* @param mediaSource The new {@link MediaSource}.
* @param resetPosition Whether the playback position should be reset to the default position. If
* false, playback will start from the position defined by {@link #getCurrentWindowIndex()}
* false, playback will start from the position defined by {@link #getCurrentMediaItemIndex()}
* and {@link #getCurrentPosition()}.
*/
void setMediaSource(MediaSource mediaSource, boolean resetPosition);
......@@ -1331,9 +1332,9 @@ public interface ExoPlayer extends Player {
* will be delivered immediately without blocking on the playback thread. The default {@link
* PlayerMessage#getType()} is 0 and the default {@link PlayerMessage#getPayload()} is null. If a
* position is specified with {@link PlayerMessage#setPosition(long)}, the message will be
* delivered at this position in the current window defined by {@link #getCurrentWindowIndex()}.
* Alternatively, the message can be sent at a specific window using {@link
* PlayerMessage#setPosition(int, long)}.
* delivered at this position in the current media item defined by {@link
* #getCurrentMediaItemIndex()}. Alternatively, the message can be sent at a specific mediaItem
* using {@link PlayerMessage#setPosition(int, long)}.
*/
PlayerMessage createMessage(PlayerMessage.Target target);
......
......@@ -537,7 +537,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
playbackInfo,
timeline,
getPeriodPositionOrMaskWindowPosition(
timeline, getCurrentWindowIndex(), getCurrentPosition()));
timeline, getCurrentMediaItemIndex(), getCurrentPosition()));
pendingOperationAcks++;
this.shuffleOrder = shuffleOrder;
internalPlayer.setShuffleOrder(shuffleOrder);
......@@ -662,7 +662,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
@Player.State
int newPlaybackState =
getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : Player.STATE_BUFFERING;
int oldMaskingWindowIndex = getCurrentWindowIndex();
int oldMaskingMediaItemIndex = getCurrentMediaItemIndex();
PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackState(newPlaybackState);
newPlaybackInfo =
maskTimelineAndPosition(
......@@ -678,7 +678,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
/* positionDiscontinuity= */ true,
/* positionDiscontinuityReason= */ DISCONTINUITY_REASON_SEEK,
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
oldMaskingWindowIndex);
oldMaskingMediaItemIndex);
}
@Override
......@@ -839,7 +839,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
internalPlayer,
target,
playbackInfo.timeline,
getCurrentWindowIndex(),
getCurrentMediaItemIndex(),
clock,
internalPlayer.getPlaybackLooper());
}
......@@ -910,7 +910,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
if (isPlayingAd()) {
playbackInfo.timeline.getPeriodByUid(playbackInfo.periodId.periodUid, period);
return playbackInfo.requestedContentPositionUs == C.TIME_UNSET
? playbackInfo.timeline.getWindow(getCurrentWindowIndex(), window).getDefaultPositionMs()
? playbackInfo
.timeline
.getWindow(getCurrentMediaItemIndex(), window)
.getDefaultPositionMs()
: period.getPositionInWindowMs() + Util.usToMs(playbackInfo.requestedContentPositionUs);
} else {
return getCurrentPosition();
......@@ -924,7 +927,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
if (playbackInfo.loadingMediaPeriodId.windowSequenceNumber
!= playbackInfo.periodId.windowSequenceNumber) {
return playbackInfo.timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs();
return playbackInfo.timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
}
long contentBufferedPositionUs = playbackInfo.bufferedPositionUs;
if (playbackInfo.loadingMediaPeriodId.isAd()) {
......@@ -1218,7 +1221,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
boolean positionDiscontinuity,
@DiscontinuityReason int positionDiscontinuityReason,
long discontinuityWindowStartPositionUs,
int oldMaskingWindowIndex) {
int oldMaskingMediaItemIndex) {
// Assign playback info immediately such that all getters return the right values, but keep
// snapshot of previous and new state so that listener invocations are triggered correctly.
......@@ -1267,7 +1270,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
if (positionDiscontinuity) {
PositionInfo previousPositionInfo =
getPreviousPositionInfo(
positionDiscontinuityReason, previousPlaybackInfo, oldMaskingWindowIndex);
positionDiscontinuityReason, previousPlaybackInfo, oldMaskingMediaItemIndex);
PositionInfo positionInfo = getPositionInfo(discontinuityWindowStartPositionUs);
listeners.queueEvent(
Player.EVENT_POSITION_DISCONTINUITY,
......@@ -1378,19 +1381,19 @@ import java.util.concurrent.CopyOnWriteArraySet;
private PositionInfo getPreviousPositionInfo(
@DiscontinuityReason int positionDiscontinuityReason,
PlaybackInfo oldPlaybackInfo,
int oldMaskingWindowIndex) {
int oldMaskingMediaItemIndex) {
@Nullable Object oldWindowUid = null;
@Nullable Object oldPeriodUid = null;
int oldWindowIndex = oldMaskingWindowIndex;
int oldMediaItemIndex = oldMaskingMediaItemIndex;
int oldPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem oldMediaItem = null;
Timeline.Period oldPeriod = new Timeline.Period();
if (!oldPlaybackInfo.timeline.isEmpty()) {
oldPeriodUid = oldPlaybackInfo.periodId.periodUid;
oldPlaybackInfo.timeline.getPeriodByUid(oldPeriodUid, oldPeriod);
oldWindowIndex = oldPeriod.windowIndex;
oldMediaItemIndex = oldPeriod.windowIndex;
oldPeriodIndex = oldPlaybackInfo.timeline.getIndexOfPeriod(oldPeriodUid);
oldWindowUid = oldPlaybackInfo.timeline.getWindow(oldWindowIndex, window).uid;
oldWindowUid = oldPlaybackInfo.timeline.getWindow(oldMediaItemIndex, window).uid;
oldMediaItem = window.mediaItem;
}
long oldPositionUs;
......@@ -1421,7 +1424,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
}
return new PositionInfo(
oldWindowUid,
oldWindowIndex,
oldMediaItemIndex,
oldMediaItem,
oldPeriodUid,
oldPeriodIndex,
......@@ -1434,20 +1437,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
private PositionInfo getPositionInfo(long discontinuityWindowStartPositionUs) {
@Nullable Object newWindowUid = null;
@Nullable Object newPeriodUid = null;
int newWindowIndex = getCurrentWindowIndex();
int newMediaItemIndex = getCurrentMediaItemIndex();
int newPeriodIndex = C.INDEX_UNSET;
@Nullable MediaItem newMediaItem = null;
if (!playbackInfo.timeline.isEmpty()) {
newPeriodUid = playbackInfo.periodId.periodUid;
playbackInfo.timeline.getPeriodByUid(newPeriodUid, period);
newPeriodIndex = playbackInfo.timeline.getIndexOfPeriod(newPeriodUid);
newWindowUid = playbackInfo.timeline.getWindow(newWindowIndex, window).uid;
newWindowUid = playbackInfo.timeline.getWindow(newMediaItemIndex, window).uid;
newMediaItem = window.mediaItem;
}
long positionMs = Util.usToMs(discontinuityWindowStartPositionUs);
return new PositionInfo(
newWindowUid,
newWindowIndex,
newMediaItemIndex,
newMediaItem,
newPeriodUid,
newPeriodIndex,
......@@ -1601,7 +1604,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
private PlaybackInfo removeMediaItemsInternal(int fromIndex, int toIndex) {
Assertions.checkArgument(
fromIndex >= 0 && toIndex >= fromIndex && toIndex <= mediaSourceHolderSnapshots.size());
int currentWindowIndex = getCurrentWindowIndex();
int currentIndex = getCurrentMediaItemIndex();
Timeline oldTimeline = getCurrentTimeline();
int currentMediaSourceCount = mediaSourceHolderSnapshots.size();
pendingOperationAcks++;
......@@ -1618,7 +1621,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
&& newPlaybackInfo.playbackState != STATE_ENDED
&& fromIndex < toIndex
&& toIndex == currentMediaSourceCount
&& currentWindowIndex >= newPlaybackInfo.timeline.getWindowCount();
&& currentIndex >= newPlaybackInfo.timeline.getWindowCount();
if (transitionsToEnded) {
newPlaybackInfo = newPlaybackInfo.copyWithPlaybackState(STATE_ENDED);
}
......@@ -1753,11 +1756,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
isCleared ? C.INDEX_UNSET : getCurrentWindowIndexInternal(),
isCleared ? C.TIME_UNSET : currentPositionMs);
}
int currentWindowIndex = getCurrentWindowIndex();
int currentMediaItemIndex = getCurrentMediaItemIndex();
@Nullable
Pair<Object, Long> oldPeriodPosition =
oldTimeline.getPeriodPosition(
window, period, currentWindowIndex, Util.msToUs(currentPositionMs));
window, period, currentMediaItemIndex, Util.msToUs(currentPositionMs));
Object periodUid = castNonNull(oldPeriodPosition).first;
if (newTimeline.getIndexOfPeriod(periodUid) != C.INDEX_UNSET) {
// The old period position is still available in the new timeline.
......
......@@ -2718,7 +2718,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
newTimeline,
new SeekPosition(
pendingMessageInfo.message.getTimeline(),
pendingMessageInfo.message.getWindowIndex(),
pendingMessageInfo.message.getMediaItemIndex(),
requestPositionUs),
/* trySubsequentPeriods= */ false,
repeatMode,
......
......@@ -63,7 +63,7 @@ public final class PlayerMessage {
private int type;
@Nullable private Object payload;
private Looper looper;
private int windowIndex;
private int mediaItemIndex;
private long positionMs;
private boolean deleteAfterDelivery;
private boolean isSent;
......@@ -78,8 +78,8 @@ public final class PlayerMessage {
* @param target The {@link Target} the message is sent to.
* @param timeline The timeline used when setting the position with {@link #setPosition(long)}. If
* set to {@link Timeline#EMPTY}, any position can be specified.
* @param defaultWindowIndex The default window index in the {@code timeline} when no other window
* index is specified.
* @param defaultMediaItemIndex The default media item index in the {@code timeline} when no other
* media item index is specified.
* @param clock The {@link Clock}.
* @param defaultLooper The default {@link Looper} to send the message on when no other looper is
* specified.
......@@ -88,7 +88,7 @@ public final class PlayerMessage {
Sender sender,
Target target,
Timeline timeline,
int defaultWindowIndex,
int defaultMediaItemIndex,
Clock clock,
Looper defaultLooper) {
this.sender = sender;
......@@ -96,7 +96,7 @@ public final class PlayerMessage {
this.timeline = timeline;
this.looper = defaultLooper;
this.clock = clock;
this.windowIndex = defaultWindowIndex;
this.mediaItemIndex = defaultMediaItemIndex;
this.positionMs = C.TIME_UNSET;
this.deleteAfterDelivery = true;
}
......@@ -173,21 +173,21 @@ public final class PlayerMessage {
}
/**
* Returns position in window at {@link #getWindowIndex()} at which the message will be delivered,
* in milliseconds. If {@link C#TIME_UNSET}, the message will be delivered immediately. If {@link
* C#TIME_END_OF_SOURCE}, the message will be delivered at the end of the window at {@link
* #getWindowIndex()}.
* Returns position in the media item at {@link #getMediaItemIndex()} at which the message will be
* delivered, in milliseconds. If {@link C#TIME_UNSET}, the message will be delivered immediately.
* If {@link C#TIME_END_OF_SOURCE}, the message will be delivered at the end of the media item at
* {@link #getMediaItemIndex()}.
*/
public long getPositionMs() {
return positionMs;
}
/**
* Sets a position in the current window at which the message will be delivered.
* Sets a position in the current media item at which the message will be delivered.
*
* @param positionMs The position in the current window at which the message will be sent, in
* @param positionMs The position in the current media item at which the message will be sent, in
* milliseconds, or {@link C#TIME_END_OF_SOURCE} to deliver the message at the end of the
* current window.
* current media item.
* @return This message.
* @throws IllegalStateException If {@link #send()} has already been called.
*/
......@@ -198,31 +198,32 @@ public final class PlayerMessage {
}
/**
* Sets a position in a window at which the message will be delivered.
* Sets a position in a media item at which the message will be delivered.
*
* @param windowIndex The index of the window at which the message will be sent.
* @param positionMs The position in the window with index {@code windowIndex} at which the
* @param mediaItemIndex The index of the media item at which the message will be sent.
* @param positionMs The position in the media item with index {@code mediaItemIndex} at which the
* message will be sent, in milliseconds, or {@link C#TIME_END_OF_SOURCE} to deliver the
* message at the end of the window with index {@code windowIndex}.
* message at the end of the media item with index {@code mediaItemIndex}.
* @return This message.
* @throws IllegalSeekPositionException If the timeline returned by {@link #getTimeline()} is not
* empty and the provided window index is not within the bounds of the timeline.
* empty and the provided media item index is not within the bounds of the timeline.
* @throws IllegalStateException If {@link #send()} has already been called.
*/
public PlayerMessage setPosition(int windowIndex, long positionMs) {
public PlayerMessage setPosition(int mediaItemIndex, long positionMs) {
Assertions.checkState(!isSent);
Assertions.checkArgument(positionMs != C.TIME_UNSET);
if (windowIndex < 0 || (!timeline.isEmpty() && windowIndex >= timeline.getWindowCount())) {
throw new IllegalSeekPositionException(timeline, windowIndex, positionMs);
if (mediaItemIndex < 0
|| (!timeline.isEmpty() && mediaItemIndex >= timeline.getWindowCount())) {
throw new IllegalSeekPositionException(timeline, mediaItemIndex, positionMs);
}
this.windowIndex = windowIndex;
this.mediaItemIndex = mediaItemIndex;
this.positionMs = positionMs;
return this;
}
/** Returns window index at which the message will be delivered. */
public int getWindowIndex() {
return windowIndex;
/** Returns media item index at which the message will be delivered. */
public int getMediaItemIndex() {
return mediaItemIndex;
}
/**
......
......@@ -1110,9 +1110,9 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public void setMediaSources(
List<MediaSource> mediaSources, int startWindowIndex, long startPositionMs) {
List<MediaSource> mediaSources, int startMediaItemIndex, long startPositionMs) {
verifyApplicationThread();
player.setMediaSources(mediaSources, startWindowIndex, startPositionMs);
player.setMediaSources(mediaSources, startMediaItemIndex, startPositionMs);
}
@Override
......@@ -1419,7 +1419,7 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public int getCurrentMediaItemIndex() {
verifyApplicationThread();
return player.getCurrentWindowIndex();
return player.getCurrentMediaItemIndex();
}
@Override
......
......@@ -914,7 +914,7 @@ public class AnalyticsCollector
long eventPositionMs;
boolean isInCurrentWindow =
timeline.equals(player.getCurrentTimeline())
&& windowIndex == player.getCurrentWindowIndex();
&& windowIndex == player.getCurrentMediaItemIndex();
if (mediaPeriodId != null && mediaPeriodId.isAd()) {
boolean isCurrentAd =
isInCurrentWindow
......@@ -939,7 +939,7 @@ public class AnalyticsCollector
mediaPeriodId,
eventPositionMs,
player.getCurrentTimeline(),
player.getCurrentWindowIndex(),
player.getCurrentMediaItemIndex(),
currentMediaPeriodId,
player.getCurrentPosition(),
player.getTotalBufferedDuration());
......@@ -962,7 +962,7 @@ public class AnalyticsCollector
? null
: mediaPeriodQueueTracker.getMediaPeriodIdTimeline(mediaPeriodId);
if (mediaPeriodId == null || knownTimeline == null) {
int windowIndex = player.getCurrentWindowIndex();
int windowIndex = player.getCurrentMediaItemIndex();
Timeline timeline = player.getCurrentTimeline();
boolean windowIsInTimeline = windowIndex < timeline.getWindowCount();
return generateEventTime(
......
......@@ -382,7 +382,7 @@ public interface AnalyticsListener {
/**
* The current window index in {@link #currentTimeline} at the time of the event, or the
* prospective window index if the timeline is not yet known and empty (equivalent to {@link
* Player#getCurrentWindowIndex()}).
* Player#getCurrentMediaItemIndex()}).
*/
public final int currentWindowIndex;
......@@ -419,7 +419,7 @@ public interface AnalyticsListener {
* {@link Player#getCurrentTimeline()}).
* @param currentWindowIndex The current window index in {@code currentTimeline} at the time of
* the event, or the prospective window index if the timeline is not yet known and empty
* (equivalent to {@link Player#getCurrentWindowIndex()}).
* (equivalent to {@link Player#getCurrentMediaItemIndex()}).
* @param currentMediaPeriodId {@link MediaPeriodId Media period identifier} for the currently
* playing media period at the time of the event, or {@code null} if no current media period
* identifier is available.
......@@ -1204,9 +1204,9 @@ public interface AnalyticsListener {
* {@link Player#seekTo(long)} after a {@link
* AnalyticsListener#onMediaItemTransition(EventTime, MediaItem, int)}).
* <li>They intend to use multiple state values together or in combination with {@link Player}
* getter methods. For example using {@link Player#getCurrentWindowIndex()} with the {@code
* timeline} provided in {@link #onTimelineChanged(EventTime, int)} is only safe from within
* this method.
* getter methods. For example using {@link Player#getCurrentMediaItemIndex()} with the
* {@code timeline} provided in {@link #onTimelineChanged(EventTime, int)} is only safe from
* within this method.
* <li>They are interested in events that logically happened together (e.g {@link
* #onPlaybackStateChanged(EventTime, int)} to {@link Player#STATE_BUFFERING} because of
* {@link #onMediaItemTransition(EventTime, MediaItem, int)}).
......
......@@ -182,6 +182,8 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
mediaDrm.closeSession(sessionId);
}
// Return values of MediaDrm.KeyRequest.getRequestType are equal to KeyRequest.RequestType.
@SuppressLint("WrongConstant")
@Override
public KeyRequest getKeyRequest(
byte[] scope,
......
......@@ -138,8 +138,8 @@ public class DebugTextViewHelper implements Player.Listener, Runnable {
break;
}
return String.format(
"playWhenReady:%s playbackState:%s window:%s",
player.getPlayWhenReady(), playbackStateString, player.getCurrentWindowIndex());
"playWhenReady:%s playbackState:%s item:%s",
player.getPlayWhenReady(), playbackStateString, player.getCurrentMediaItemIndex());
}
/** Returns a string containing video debugging information. */
......
......@@ -950,7 +950,7 @@ public class PlayerControlView extends FrameLayout {
int adGroupCount = 0;
Timeline timeline = player.getCurrentTimeline();
if (!timeline.isEmpty()) {
int currentWindowIndex = player.getCurrentWindowIndex();
int currentWindowIndex = player.getCurrentMediaItemIndex();
int firstWindowIndex = multiWindowTimeBar ? 0 : currentWindowIndex;
int lastWindowIndex = multiWindowTimeBar ? timeline.getWindowCount() - 1 : currentWindowIndex;
for (int i = firstWindowIndex; i <= lastWindowIndex; i++) {
......@@ -1110,7 +1110,7 @@ public class PlayerControlView extends FrameLayout {
windowIndex++;
}
} else {
windowIndex = player.getCurrentWindowIndex();
windowIndex = player.getCurrentMediaItemIndex();
}
seekTo(player, windowIndex, positionMs);
updateProgress();
......@@ -1228,7 +1228,7 @@ public class PlayerControlView extends FrameLayout {
if (state == Player.STATE_IDLE) {
player.prepare();
} else if (state == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET);
}
player.play();
}
......
......@@ -605,9 +605,9 @@ public class PlayerNotificationManager {
public static final String ACTION_PLAY = "com.google.android.exoplayer.play";
/** The action which pauses playback. */
public static final String ACTION_PAUSE = "com.google.android.exoplayer.pause";
/** The action which skips to the previous window. */
/** The action which skips to the previous media item. */
public static final String ACTION_PREVIOUS = "com.google.android.exoplayer.prev";
/** The action which skips to the next window. */
/** The action which skips to the next media item. */
public static final String ACTION_NEXT = "com.google.android.exoplayer.next";
/** The action which fast forwards. */
public static final String ACTION_FAST_FORWARD = "com.google.android.exoplayer.ffwd";
......@@ -1095,7 +1095,7 @@ public class PlayerNotificationManager {
*
* <ul>
* <li>The media is {@link Player#isPlaying() actively playing}.
* <li>The media is not {@link Player#isCurrentWindowDynamic() dynamically changing its
* <li>The media is not {@link Player#isCurrentMediaItemDynamic() dynamically changing its
* duration} (like for example a live stream).
* <li>The media is not {@link Player#isPlayingAd() interrupted by an ad}.
* <li>The media is played at {@link Player#getPlaybackParameters() regular speed}.
......@@ -1253,7 +1253,7 @@ public class PlayerNotificationManager {
&& useChronometer
&& player.isPlaying()
&& !player.isPlayingAd()
&& !player.isCurrentWindowDynamic()
&& !player.isCurrentMediaItemDynamic()
&& player.getPlaybackParameters().speed == 1f) {
builder
.setWhen(System.currentTimeMillis() - player.getContentPosition())
......@@ -1531,7 +1531,7 @@ public class PlayerNotificationManager {
if (player.getPlaybackState() == Player.STATE_IDLE) {
player.prepare();
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
player.seekToDefaultPosition(player.getCurrentWindowIndex());
player.seekToDefaultPosition(player.getCurrentMediaItemIndex());
}
player.play();
} else if (ACTION_PAUSE.equals(action)) {
......
......@@ -1501,8 +1501,8 @@ public class PlayerView extends FrameLayout implements AdViewProvider {
if (lastPeriodIndexWithTracks != C.INDEX_UNSET) {
int lastWindowIndexWithTracks =
timeline.getPeriod(lastPeriodIndexWithTracks, period).windowIndex;
if (player.getCurrentWindowIndex() == lastWindowIndexWithTracks) {
// We're in the same window. Suppress the update.
if (player.getCurrentMediaItemIndex() == lastWindowIndexWithTracks) {
// We're in the same media item. Suppress the update.
return;
}
}
......
......@@ -1269,7 +1269,7 @@ public class StyledPlayerControlView extends FrameLayout {
int adGroupCount = 0;
Timeline timeline = player.getCurrentTimeline();
if (!timeline.isEmpty()) {
int currentWindowIndex = player.getCurrentWindowIndex();
int currentWindowIndex = player.getCurrentMediaItemIndex();
int firstWindowIndex = multiWindowTimeBar ? 0 : currentWindowIndex;
int lastWindowIndex = multiWindowTimeBar ? timeline.getWindowCount() - 1 : currentWindowIndex;
for (int i = firstWindowIndex; i <= lastWindowIndex; i++) {
......@@ -1453,7 +1453,7 @@ public class StyledPlayerControlView extends FrameLayout {
windowIndex++;
}
} else {
windowIndex = player.getCurrentWindowIndex();
windowIndex = player.getCurrentMediaItemIndex();
}
seekTo(player, windowIndex, positionMs);
updateProgress();
......@@ -1616,13 +1616,12 @@ public class StyledPlayerControlView extends FrameLayout {
}
}
@SuppressWarnings("deprecation")
private void dispatchPlay(Player player) {
@State int state = player.getPlaybackState();
if (state == Player.STATE_IDLE) {
player.prepare();
} else if (state == Player.STATE_ENDED) {
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET);
}
player.play();
}
......
......@@ -1540,8 +1540,8 @@ public class StyledPlayerView extends FrameLayout implements AdViewProvider {
if (lastPeriodIndexWithTracks != C.INDEX_UNSET) {
int lastWindowIndexWithTracks =
timeline.getPeriod(lastPeriodIndexWithTracks, period).windowIndex;
if (player.getCurrentWindowIndex() == lastWindowIndexWithTracks) {
// We're in the same window. Suppress the update.
if (player.getCurrentMediaItemIndex() == lastWindowIndexWithTracks) {
// We're in the same media item. Suppress the update.
return;
}
}
......
......@@ -284,12 +284,12 @@ public class TestPlayerRunHelper {
* <p>If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param windowIndex The window.
* @param positionMs The position within the window, in milliseconds.
* @param mediaItemIndex The index of the media item.
* @param positionMs The position within the media item, in milliseconds.
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
* exceeded.
*/
public static void playUntilPosition(ExoPlayer player, int windowIndex, long positionMs)
public static void playUntilPosition(ExoPlayer player, int mediaItemIndex, long positionMs)
throws TimeoutException {
verifyMainTestThread(player);
Looper applicationLooper = Util.getCurrentOrMainLooper();
......@@ -315,7 +315,7 @@ public class TestPlayerRunHelper {
// Ignore.
}
})
.setPosition(windowIndex, positionMs)
.setPosition(mediaItemIndex, positionMs)
.send();
player.play();
runMainLooperUntil(() -> messageHandled.get() || player.getPlayerError() != null);
......@@ -326,18 +326,19 @@ public class TestPlayerRunHelper {
/**
* Calls {@link Player#play()}, runs tasks of the main {@link Looper} until the {@code player}
* reaches the specified window or a playback error occurs, and then pauses the {@code player}.
* reaches the specified media item or a playback error occurs, and then pauses the {@code
* player}.
*
* <p>If a playback error occurs it will be thrown wrapped in an {@link IllegalStateException}.
*
* @param player The {@link Player}.
* @param windowIndex The window.
* @param mediaItemIndex The index of the media item.
* @throws TimeoutException If the {@link RobolectricUtil#DEFAULT_TIMEOUT_MS default timeout} is
* exceeded.
*/
public static void playUntilStartOfWindow(ExoPlayer player, int windowIndex)
public static void playUntilStartOfMediaItem(ExoPlayer player, int mediaItemIndex)
throws TimeoutException {
playUntilPosition(player, windowIndex, /* positionMs= */ 0);
playUntilPosition(player, mediaItemIndex, /* positionMs= */ 0);
}
/**
......
......@@ -121,7 +121,7 @@ public abstract class Action {
/** Calls {@link Player#seekTo(long)} or {@link Player#seekTo(int, long)}. */
public static final class Seek extends Action {
@Nullable private final Integer windowIndex;
@Nullable private final Integer mediaItemIndex;
private final long positionMs;
private final boolean catchIllegalSeekException;
......@@ -133,7 +133,7 @@ public abstract class Action {
*/
public Seek(String tag, long positionMs) {
super(tag, "Seek:" + positionMs);
this.windowIndex = null;
this.mediaItemIndex = null;
this.positionMs = positionMs;
catchIllegalSeekException = false;
}
......@@ -142,14 +142,15 @@ public abstract class Action {
* Action calls {@link Player#seekTo(int, long)}.
*
* @param tag A tag to use for logging.
* @param windowIndex The window to seek to.
* @param mediaItemIndex The media item to seek to.
* @param positionMs The seek position.
* @param catchIllegalSeekException Whether {@link IllegalSeekPositionException} should be
* silently caught or not.
*/
public Seek(String tag, int windowIndex, long positionMs, boolean catchIllegalSeekException) {
public Seek(
String tag, int mediaItemIndex, long positionMs, boolean catchIllegalSeekException) {
super(tag, "Seek:" + positionMs);
this.windowIndex = windowIndex;
this.mediaItemIndex = mediaItemIndex;
this.positionMs = positionMs;
this.catchIllegalSeekException = catchIllegalSeekException;
}
......@@ -158,10 +159,10 @@ public abstract class Action {
protected void doActionImpl(
ExoPlayer player, DefaultTrackSelector trackSelector, @Nullable Surface surface) {
try {
if (windowIndex == null) {
if (mediaItemIndex == null) {
player.seekTo(positionMs);
} else {
player.seekTo(windowIndex, positionMs);
player.seekTo(mediaItemIndex, positionMs);
}
} catch (IllegalSeekPositionException e) {
if (!catchIllegalSeekException) {
......@@ -174,20 +175,20 @@ public abstract class Action {
/** Calls {@link ExoPlayer#setMediaSources(List, int, long)}. */
public static final class SetMediaItems extends Action {
private final int windowIndex;
private final int mediaItemIndex;
private final long positionMs;
private final MediaSource[] mediaSources;
/**
* @param tag A tag to use for logging.
* @param windowIndex The window index to start playback from.
* @param mediaItemIndex The media item index to start playback from.
* @param positionMs The position in milliseconds to start playback from.
* @param mediaSources The media sources to populate the playlist with.
*/
public SetMediaItems(
String tag, int windowIndex, long positionMs, MediaSource... mediaSources) {
String tag, int mediaItemIndex, long positionMs, MediaSource... mediaSources) {
super(tag, "SetMediaItems");
this.windowIndex = windowIndex;
this.mediaItemIndex = mediaItemIndex;
this.positionMs = positionMs;
this.mediaSources = mediaSources;
}
......@@ -195,7 +196,7 @@ public abstract class Action {
@Override
protected void doActionImpl(
ExoPlayer player, DefaultTrackSelector trackSelector, @Nullable Surface surface) {
player.setMediaSources(Arrays.asList(mediaSources), windowIndex, positionMs);
player.setMediaSources(Arrays.asList(mediaSources), mediaItemIndex, positionMs);
}
}
......@@ -553,7 +554,7 @@ public abstract class Action {
public static final class SendMessages extends Action {
private final Target target;
private final int windowIndex;
private final int mediaItemIndex;
private final long positionMs;
private final boolean deleteAfterDelivery;
......@@ -566,7 +567,7 @@ public abstract class Action {
this(
tag,
target,
/* windowIndex= */ C.INDEX_UNSET,
/* mediaItemIndex= */ C.INDEX_UNSET,
positionMs,
/* deleteAfterDelivery= */ true);
}
......@@ -574,16 +575,20 @@ public abstract class Action {
/**
* @param tag A tag to use for logging.
* @param target A message target.
* @param windowIndex The window index at which the message should be sent, or {@link
* C#INDEX_UNSET} for the current window.
* @param mediaItemIndex The media item index at which the message should be sent, or {@link
* C#INDEX_UNSET} for the current media item.
* @param positionMs The position at which the message should be sent, in milliseconds.
* @param deleteAfterDelivery Whether the message will be deleted after delivery.
*/
public SendMessages(
String tag, Target target, int windowIndex, long positionMs, boolean deleteAfterDelivery) {
String tag,
Target target,
int mediaItemIndex,
long positionMs,
boolean deleteAfterDelivery) {
super(tag, "SendMessages");
this.target = target;
this.windowIndex = windowIndex;
this.mediaItemIndex = mediaItemIndex;
this.positionMs = positionMs;
this.deleteAfterDelivery = deleteAfterDelivery;
}
......@@ -595,8 +600,8 @@ public abstract class Action {
((PlayerTarget) target).setPlayer(player);
}
PlayerMessage message = player.createMessage(target);
if (windowIndex != C.INDEX_UNSET) {
message.setPosition(windowIndex, positionMs);
if (mediaItemIndex != C.INDEX_UNSET) {
message.setPosition(mediaItemIndex, positionMs);
} else {
message.setPosition(positionMs);
}
......@@ -661,17 +666,17 @@ public abstract class Action {
*/
public static final class PlayUntilPosition extends Action {
private final int windowIndex;
private final int mediaItemIndex;
private final long positionMs;
/**
* @param tag A tag to use for logging.
* @param windowIndex The window index at which the player should be paused again.
* @param positionMs The position in that window at which the player should be paused again.
* @param mediaItemIndex The media item index at which the player should be paused again.
* @param positionMs The position in that media item at which the player should be paused again.
*/
public PlayUntilPosition(String tag, int windowIndex, long positionMs) {
super(tag, "PlayUntilPosition:" + windowIndex + ":" + positionMs);
this.windowIndex = windowIndex;
public PlayUntilPosition(String tag, int mediaItemIndex, long positionMs) {
super(tag, "PlayUntilPosition:" + mediaItemIndex + ":" + positionMs);
this.mediaItemIndex = mediaItemIndex;
this.positionMs = positionMs;
}
......@@ -704,7 +709,7 @@ public abstract class Action {
// Ignore.
}
})
.setPosition(windowIndex, positionMs)
.setPosition(mediaItemIndex, positionMs)
.send();
if (nextAction != null) {
// Schedule another message on this test thread to continue action schedule.
......@@ -712,7 +717,7 @@ public abstract class Action {
.createMessage(
(messageType, payload) ->
nextAction.schedule(player, trackSelector, surface, handler))
.setPosition(windowIndex, positionMs)
.setPosition(mediaItemIndex, positionMs)
.setLooper(applicationLooper)
.send();
}
......
......@@ -161,24 +161,25 @@ public final class ActionSchedule {
/**
* Schedules a seek action.
*
* @param windowIndex The window to seek to.
* @param mediaItemIndex The media item to seek to.
* @param positionMs The seek position.
* @return The builder, for convenience.
*/
public Builder seek(int windowIndex, long positionMs) {
return apply(new Seek(tag, windowIndex, positionMs, /* catchIllegalSeekException= */ false));
public Builder seek(int mediaItemIndex, long positionMs) {
return apply(
new Seek(tag, mediaItemIndex, positionMs, /* catchIllegalSeekException= */ false));
}
/**
* Schedules a seek action to be executed.
*
* @param windowIndex The window to seek to.
* @param mediaItemIndex The media item to seek to.
* @param positionMs The seek position.
* @param catchIllegalSeekException Whether an illegal seek position should be caught or not.
* @return The builder, for convenience.
*/
public Builder seek(int windowIndex, long positionMs, boolean catchIllegalSeekException) {
return apply(new Seek(tag, windowIndex, positionMs, catchIllegalSeekException));
public Builder seek(int mediaItemIndex, long positionMs, boolean catchIllegalSeekException) {
return apply(new Seek(tag, mediaItemIndex, positionMs, catchIllegalSeekException));
}
/**
......@@ -247,23 +248,23 @@ public final class ActionSchedule {
* Schedules a play action, waits until the player reaches the specified position, and pauses
* the player again.
*
* @param windowIndex The window index at which the player should be paused again.
* @param positionMs The position in that window at which the player should be paused again.
* @param mediaItemIndex The media item index at which the player should be paused again.
* @param positionMs The position in that media item at which the player should be paused again.
* @return The builder, for convenience.
*/
public Builder playUntilPosition(int windowIndex, long positionMs) {
return apply(new PlayUntilPosition(tag, windowIndex, positionMs));
public Builder playUntilPosition(int mediaItemIndex, long positionMs) {
return apply(new PlayUntilPosition(tag, mediaItemIndex, positionMs));
}
/**
* Schedules a play action, waits until the player reaches the start of the specified window,
* and pauses the player again.
* Schedules a play action, waits until the player reaches the start of the specified media
* item, and pauses the player again.
*
* @param windowIndex The window index at which the player should be paused again.
* @param mediaItemIndex The media item index at which the player should be paused again.
* @return The builder, for convenience.
*/
public Builder playUntilStartOfWindow(int windowIndex) {
return apply(new PlayUntilPosition(tag, windowIndex, /* positionMs= */ 0));
public Builder playUntilStartOfMediaItem(int mediaItemIndex) {
return apply(new PlayUntilPosition(tag, mediaItemIndex, /* positionMs= */ 0));
}
/**
......@@ -323,16 +324,16 @@ public final class ActionSchedule {
/**
* Schedules a set media items action to be executed.
*
* @param windowIndex The window index to start playback from or {@link C#INDEX_UNSET} if the
* playback position should not be reset.
* @param mediaItemIndex The media item index to start playback from or {@link C#INDEX_UNSET} if
* the playback position should not be reset.
* @param positionMs The position in milliseconds from where playback should start. If {@link
* C#TIME_UNSET} is passed the default position is used. In any case, if {@code windowIndex}
* is set to {@link C#INDEX_UNSET} the position is not reset at all and this parameter is
* ignored.
* C#TIME_UNSET} is passed the default position is used. In any case, if {@code
* mediaItemIndex} is set to {@link C#INDEX_UNSET} the position is not reset at all and this
* parameter is ignored.
* @return The builder, for convenience.
*/
public Builder setMediaSources(int windowIndex, long positionMs, MediaSource... sources) {
return apply(new Action.SetMediaItems(tag, windowIndex, positionMs, sources));
public Builder setMediaSources(int mediaItemIndex, long positionMs, MediaSource... sources) {
return apply(new Action.SetMediaItems(tag, mediaItemIndex, positionMs, sources));
}
/**
......@@ -354,7 +355,10 @@ public final class ActionSchedule {
public Builder setMediaSources(MediaSource... mediaSources) {
return apply(
new Action.SetMediaItems(
tag, /* windowIndex= */ C.INDEX_UNSET, /* positionMs= */ C.TIME_UNSET, mediaSources));
tag,
/* mediaItemIndex= */ C.INDEX_UNSET,
/* positionMs= */ C.TIME_UNSET,
mediaSources));
}
/**
* Schedules a add media items action to be executed.
......@@ -447,8 +451,8 @@ public final class ActionSchedule {
/**
* Schedules sending a {@link PlayerMessage}.
*
* @param positionMs The position in the current window at which the message should be sent, in
* milliseconds.
* @param positionMs The position in the current media item at which the message should be sent,
* in milliseconds.
* @return The builder, for convenience.
*/
public Builder sendMessage(Target target, long positionMs) {
......@@ -459,27 +463,28 @@ public final class ActionSchedule {
* Schedules sending a {@link PlayerMessage}.
*
* @param target A message target.
* @param windowIndex The window index at which the message should be sent.
* @param mediaItemIndex The media item index at which the message should be sent.
* @param positionMs The position at which the message should be sent, in milliseconds.
* @return The builder, for convenience.
*/
public Builder sendMessage(Target target, int windowIndex, long positionMs) {
public Builder sendMessage(Target target, int mediaItemIndex, long positionMs) {
return apply(
new SendMessages(tag, target, windowIndex, positionMs, /* deleteAfterDelivery= */ true));
new SendMessages(
tag, target, mediaItemIndex, positionMs, /* deleteAfterDelivery= */ true));
}
/**
* Schedules to send a {@link PlayerMessage}.
*
* @param target A message target.
* @param windowIndex The window index at which the message should be sent.
* @param mediaItemIndex The media item index at which the message should be sent.
* @param positionMs The position at which the message should be sent, in milliseconds.
* @param deleteAfterDelivery Whether the message will be deleted after delivery.
* @return The builder, for convenience.
*/
public Builder sendMessage(
Target target, int windowIndex, long positionMs, boolean deleteAfterDelivery) {
return apply(new SendMessages(tag, target, windowIndex, positionMs, deleteAfterDelivery));
Target target, int mediaItemIndex, long positionMs, boolean deleteAfterDelivery) {
return apply(new SendMessages(tag, target, mediaItemIndex, positionMs, deleteAfterDelivery));
}
/**
......
......@@ -85,7 +85,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
private AnalyticsListener analyticsListener;
private Integer expectedPlayerEndedCount;
private boolean pauseAtEndOfMediaItems;
private int initialWindowIndex;
private int initialMediaItemIndex;
private long initialPositionMs;
private boolean skipSettingMediaSources;
......@@ -93,7 +93,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
testPlayerBuilder = new TestExoPlayerBuilder(context);
mediaSources = new ArrayList<>();
supportedFormats = new Format[] {VIDEO_FORMAT};
initialWindowIndex = C.INDEX_UNSET;
initialMediaItemIndex = C.INDEX_UNSET;
initialPositionMs = C.TIME_UNSET;
}
......@@ -133,12 +133,12 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
/**
* Seeks before setting the media sources and preparing the player.
*
* @param windowIndex The window index to seek to.
* @param mediaItemIndex The media item index to seek to.
* @param positionMs The position in milliseconds to seek to.
* @return This builder.
*/
public Builder initialSeek(int windowIndex, long positionMs) {
this.initialWindowIndex = windowIndex;
public Builder initialSeek(int mediaItemIndex, long positionMs) {
this.initialMediaItemIndex = mediaItemIndex;
this.initialPositionMs = positionMs;
return this;
}
......@@ -343,7 +343,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
testPlayerBuilder,
mediaSources,
skipSettingMediaSources,
initialWindowIndex,
initialMediaItemIndex,
initialPositionMs,
surface,
actionSchedule,
......@@ -357,7 +357,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
private final TestExoPlayerBuilder playerBuilder;
private final List<MediaSource> mediaSources;
private final boolean skipSettingMediaSources;
private final int initialWindowIndex;
private final int initialMediaItemIndex;
private final long initialPositionMs;
@Nullable private final Surface surface;
@Nullable private final ActionSchedule actionSchedule;
......@@ -386,7 +386,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
TestExoPlayerBuilder playerBuilder,
List<MediaSource> mediaSources,
boolean skipSettingMediaSources,
int initialWindowIndex,
int initialMediaItemIndex,
long initialPositionMs,
@Nullable Surface surface,
@Nullable ActionSchedule actionSchedule,
......@@ -397,7 +397,7 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
this.playerBuilder = playerBuilder;
this.mediaSources = mediaSources;
this.skipSettingMediaSources = skipSettingMediaSources;
this.initialWindowIndex = initialWindowIndex;
this.initialMediaItemIndex = initialMediaItemIndex;
this.initialPositionMs = initialPositionMs;
this.surface = surface;
this.actionSchedule = actionSchedule;
......@@ -466,8 +466,8 @@ public final class ExoPlayerTestRunner implements Player.Listener, ActionSchedul
handler,
/* callback= */ ExoPlayerTestRunner.this);
}
if (initialWindowIndex != C.INDEX_UNSET) {
player.seekTo(initialWindowIndex, initialPositionMs);
if (initialMediaItemIndex != C.INDEX_UNSET) {
player.seekTo(initialMediaItemIndex, initialPositionMs);
}
if (!skipSettingMediaSources) {
player.setMediaSources(mediaSources, /* resetPosition= */ false);
......
......@@ -162,7 +162,7 @@ public class StubExoPlayer extends StubPlayer implements ExoPlayer {
@Override
public void setMediaSources(
List<MediaSource> mediaSources, int startWindowIndex, long startPositionMs) {
List<MediaSource> mediaSources, int startMediaItemIndex, long startPositionMs) {
throw new UnsupportedOperationException();
}
......
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