Remove ExoPlayerImpl inheritance from BasePlayer.
This inheritance is really confusing because ExoPlayerImpl is not a full Player interface implementation. It also claims to be an ExoPlayer implementation in the Javadoc which isn't true in its current state. Removing the inheritance also allows to clean up some unused methods. PiperOrigin-RevId: 411756963
This commit is contained in:
parent
6adf41f03a
commit
736ea9a148
@ -1094,7 +1094,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
|
||||
private void updateAvailableCommandsAndNotifyIfChanged() {
|
||||
Commands previousAvailableCommands = availableCommands;
|
||||
availableCommands = getAvailableCommands(PERMANENT_AVAILABLE_COMMANDS);
|
||||
availableCommands = Util.getAvailableCommands(/* player= */ this, PERMANENT_AVAILABLE_COMMANDS);
|
||||
if (!availableCommands.equals(previousAvailableCommands)) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||
|
@ -384,37 +384,6 @@ public abstract class BasePlayer implements Player {
|
||||
: timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Commands} available in the player.
|
||||
*
|
||||
* @param permanentAvailableCommands The commands permanently available in the player.
|
||||
* @return The available {@link Commands}.
|
||||
*/
|
||||
protected Commands getAvailableCommands(Commands permanentAvailableCommands) {
|
||||
return new Commands.Builder()
|
||||
.addAll(permanentAvailableCommands)
|
||||
.addIf(COMMAND_SEEK_TO_DEFAULT_POSITION, !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()
|
||||
&& (hasPreviousMediaItem()
|
||||
|| !isCurrentMediaItemLive()
|
||||
|| isCurrentMediaItemSeekable())
|
||||
&& !isPlayingAd())
|
||||
.addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNextMediaItem() && !isPlayingAd())
|
||||
.addIf(
|
||||
COMMAND_SEEK_TO_NEXT,
|
||||
!getCurrentTimeline().isEmpty()
|
||||
&& (hasNextMediaItem() || (isCurrentMediaItemLive() && isCurrentMediaItemDynamic()))
|
||||
&& !isPlayingAd())
|
||||
.addIf(COMMAND_SEEK_TO_MEDIA_ITEM, !isPlayingAd())
|
||||
.addIf(COMMAND_SEEK_BACK, isCurrentMediaItemSeekable() && !isPlayingAd())
|
||||
.addIf(COMMAND_SEEK_FORWARD, isCurrentMediaItemSeekable() && !isPlayingAd())
|
||||
.build();
|
||||
}
|
||||
|
||||
@RepeatMode
|
||||
private int getRepeatModeForNavigation() {
|
||||
@RepeatMode int repeatMode = getRepeatMode();
|
||||
|
@ -16,6 +16,15 @@
|
||||
package androidx.media3.common.util;
|
||||
|
||||
import static android.content.Context.UI_MODE_SERVICE;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_BACK;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_FORWARD;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_DEFAULT_POSITION;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.max;
|
||||
@ -64,6 +73,8 @@ import androidx.media3.common.MediaLibraryInfo;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.ParserException;
|
||||
import androidx.media3.common.PlaybackException;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.Player.Commands;
|
||||
import com.google.common.base.Ascii;
|
||||
import com.google.common.base.Charsets;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -2479,6 +2490,43 @@ public final class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Commands} available in the {@link Player}.
|
||||
*
|
||||
* @param player The {@link Player}.
|
||||
* @param permanentAvailableCommands The commands permanently available in the player.
|
||||
* @return The available {@link Commands}.
|
||||
*/
|
||||
public static Commands getAvailableCommands(Player player, Commands permanentAvailableCommands) {
|
||||
boolean isPlayingAd = player.isPlayingAd();
|
||||
boolean isCurrentMediaItemSeekable = player.isCurrentMediaItemSeekable();
|
||||
boolean hasPreviousMediaItem = player.hasPreviousMediaItem();
|
||||
boolean hasNextMediaItem = player.hasNextMediaItem();
|
||||
boolean isCurrentMediaItemLive = player.isCurrentMediaItemLive();
|
||||
boolean isCurrentMediaItemDynamic = player.isCurrentMediaItemDynamic();
|
||||
boolean isTimelineEmpty = player.getCurrentTimeline().isEmpty();
|
||||
return new Commands.Builder()
|
||||
.addAll(permanentAvailableCommands)
|
||||
.addIf(COMMAND_SEEK_TO_DEFAULT_POSITION, !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, isCurrentMediaItemSeekable && !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, hasPreviousMediaItem && !isPlayingAd)
|
||||
.addIf(
|
||||
COMMAND_SEEK_TO_PREVIOUS,
|
||||
!isTimelineEmpty
|
||||
&& (hasPreviousMediaItem || !isCurrentMediaItemLive || isCurrentMediaItemSeekable)
|
||||
&& !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, hasNextMediaItem && !isPlayingAd)
|
||||
.addIf(
|
||||
COMMAND_SEEK_TO_NEXT,
|
||||
!isTimelineEmpty
|
||||
&& (hasNextMediaItem || (isCurrentMediaItemLive && isCurrentMediaItemDynamic))
|
||||
&& !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_TO_MEDIA_ITEM, !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_BACK, isCurrentMediaItemSeekable && !isPlayingAd)
|
||||
.addIf(COMMAND_SEEK_FORWARD, isCurrentMediaItemSeekable && !isPlayingAd)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getSystemProperty(String name) {
|
||||
try {
|
||||
|
@ -15,6 +15,39 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer;
|
||||
|
||||
import static androidx.media3.common.Player.COMMAND_CHANGE_MEDIA_ITEMS;
|
||||
import static androidx.media3.common.Player.COMMAND_GET_CURRENT_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_GET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
|
||||
import static androidx.media3.common.Player.COMMAND_GET_TRACK_INFOS;
|
||||
import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
|
||||
import static androidx.media3.common.Player.COMMAND_PREPARE;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_DEFAULT_POSITION;
|
||||
import static androidx.media3.common.Player.COMMAND_SEEK_TO_MEDIA_ITEM;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_MEDIA_ITEMS_METADATA;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_REPEAT_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SHUFFLE_MODE;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_SPEED_AND_PITCH;
|
||||
import static androidx.media3.common.Player.COMMAND_SET_TRACK_SELECTION_PARAMETERS;
|
||||
import static androidx.media3.common.Player.COMMAND_STOP;
|
||||
import static androidx.media3.common.Player.DISCONTINUITY_REASON_AUTO_TRANSITION;
|
||||
import static androidx.media3.common.Player.DISCONTINUITY_REASON_INTERNAL;
|
||||
import static androidx.media3.common.Player.DISCONTINUITY_REASON_REMOVE;
|
||||
import static androidx.media3.common.Player.DISCONTINUITY_REASON_SEEK;
|
||||
import static androidx.media3.common.Player.EVENT_MEDIA_METADATA_CHANGED;
|
||||
import static androidx.media3.common.Player.EVENT_PLAYLIST_METADATA_CHANGED;
|
||||
import static androidx.media3.common.Player.EVENT_TRACK_SELECTION_PARAMETERS_CHANGED;
|
||||
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
|
||||
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
|
||||
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT;
|
||||
import static androidx.media3.common.Player.MEDIA_ITEM_TRANSITION_REASON_SEEK;
|
||||
import static androidx.media3.common.Player.PLAYBACK_SUPPRESSION_REASON_NONE;
|
||||
import static androidx.media3.common.Player.PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST;
|
||||
import static androidx.media3.common.Player.STATE_BUFFERING;
|
||||
import static androidx.media3.common.Player.STATE_ENDED;
|
||||
import static androidx.media3.common.Player.STATE_IDLE;
|
||||
import static androidx.media3.common.Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED;
|
||||
import static androidx.media3.common.Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static androidx.media3.common.util.Util.castNonNull;
|
||||
@ -26,17 +59,10 @@ import android.media.metrics.LogSessionId;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Pair;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import androidx.annotation.DoNotInline;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.BasePlayer;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.DeviceInfo;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.IllegalSeekPositionException;
|
||||
import androidx.media3.common.MediaItem;
|
||||
@ -46,14 +72,23 @@ import androidx.media3.common.Metadata;
|
||||
import androidx.media3.common.PlaybackException;
|
||||
import androidx.media3.common.PlaybackParameters;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.Player.Commands;
|
||||
import androidx.media3.common.Player.DiscontinuityReason;
|
||||
import androidx.media3.common.Player.EventListener;
|
||||
import androidx.media3.common.Player.Events;
|
||||
import androidx.media3.common.Player.Listener;
|
||||
import androidx.media3.common.Player.PlayWhenReadyChangeReason;
|
||||
import androidx.media3.common.Player.PlaybackSuppressionReason;
|
||||
import androidx.media3.common.Player.PositionInfo;
|
||||
import androidx.media3.common.Player.RepeatMode;
|
||||
import androidx.media3.common.Player.State;
|
||||
import androidx.media3.common.Player.TimelineChangeReason;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackGroup;
|
||||
import androidx.media3.common.TrackGroupArray;
|
||||
import androidx.media3.common.TrackSelectionArray;
|
||||
import androidx.media3.common.TrackSelectionParameters;
|
||||
import androidx.media3.common.TracksInfo;
|
||||
import androidx.media3.common.VideoSize;
|
||||
import androidx.media3.common.text.Cue;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.HandlerWrapper;
|
||||
@ -78,8 +113,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/** An {@link ExoPlayer} implementation. */
|
||||
/* package */ final class ExoPlayerImpl extends BasePlayer {
|
||||
/** A helper class for the {@link SimpleExoPlayer} implementation of {@link ExoPlayer}. */
|
||||
/* package */ final class ExoPlayerImpl {
|
||||
|
||||
static {
|
||||
MediaLibraryInfo.registerModule("media3.exoplayer");
|
||||
@ -97,6 +132,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* package */ final TrackSelectorResult emptyTrackSelectorResult;
|
||||
/* package */ final Commands permanentAvailableCommands;
|
||||
|
||||
private final Player wrappingPlayer;
|
||||
private final Renderer[] renderers;
|
||||
private final TrackSelector trackSelector;
|
||||
private final HandlerWrapper playbackInfoUpdateHandler;
|
||||
@ -105,10 +141,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
private final ListenerSet<Player.EventListener> listeners;
|
||||
private final CopyOnWriteArraySet<AudioOffloadListener> audioOffloadListeners;
|
||||
private final Timeline.Period period;
|
||||
private final Timeline.Window window;
|
||||
private final List<MediaSourceHolderSnapshot> mediaSourceHolderSnapshots;
|
||||
private final boolean useLazyPreparation;
|
||||
private final MediaSourceFactory mediaSourceFactory;
|
||||
@Nullable private final AnalyticsCollector analyticsCollector;
|
||||
private final AnalyticsCollector analyticsCollector;
|
||||
private final Looper applicationLooper;
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final long seekBackIncrementMs;
|
||||
@ -154,16 +191,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
* loads and other initial preparation steps happen immediately. If true, these initial
|
||||
* preparations are triggered only when the player starts buffering the media.
|
||||
* @param seekParameters The {@link SeekParameters}.
|
||||
* @param seekBackIncrementMs The {@link #seekBack()} increment in milliseconds.
|
||||
* @param seekForwardIncrementMs The {@link #seekForward()} increment in milliseconds.
|
||||
* @param seekBackIncrementMs The seek back increment in milliseconds.
|
||||
* @param seekForwardIncrementMs The seek forward increment in milliseconds.
|
||||
* @param livePlaybackSpeedControl The {@link LivePlaybackSpeedControl}.
|
||||
* @param releaseTimeoutMs The timeout for calls to {@link #release()} in milliseconds.
|
||||
* @param pauseAtEndOfMediaItems Whether to pause playback at the end of each media item.
|
||||
* @param clock The {@link Clock}.
|
||||
* @param applicationLooper The {@link Looper} that must be used for all calls to the player and
|
||||
* which is used to call listeners on.
|
||||
* @param wrappingPlayer The {@link Player} wrapping this one if applicable. This player instance
|
||||
* should be used for all externally visible callbacks.
|
||||
* @param wrappingPlayer The {@link Player} using this class.
|
||||
* @param additionalPermanentAvailableCommands The {@link Commands} that are permanently available
|
||||
* in the wrapping player but that are not in this player.
|
||||
*/
|
||||
@ -174,7 +210,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
MediaSourceFactory mediaSourceFactory,
|
||||
LoadControl loadControl,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
@Nullable AnalyticsCollector analyticsCollector,
|
||||
AnalyticsCollector analyticsCollector,
|
||||
boolean useLazyPreparation,
|
||||
SeekParameters seekParameters,
|
||||
long seekBackIncrementMs,
|
||||
@ -184,7 +220,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
boolean pauseAtEndOfMediaItems,
|
||||
Clock clock,
|
||||
Looper applicationLooper,
|
||||
@Nullable Player wrappingPlayer,
|
||||
Player wrappingPlayer,
|
||||
Commands additionalPermanentAvailableCommands) {
|
||||
Log.i(
|
||||
TAG,
|
||||
@ -208,13 +244,13 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
|
||||
this.applicationLooper = applicationLooper;
|
||||
this.clock = clock;
|
||||
this.wrappingPlayer = wrappingPlayer;
|
||||
repeatMode = Player.REPEAT_MODE_OFF;
|
||||
Player playerForListeners = wrappingPlayer != null ? wrappingPlayer : this;
|
||||
listeners =
|
||||
new ListenerSet<>(
|
||||
applicationLooper,
|
||||
clock,
|
||||
(listener, flags) -> listener.onEvents(playerForListeners, new Events(flags)));
|
||||
(listener, flags) -> listener.onEvents(wrappingPlayer, new Events(flags)));
|
||||
audioOffloadListeners = new CopyOnWriteArraySet<>();
|
||||
mediaSourceHolderSnapshots = new ArrayList<>();
|
||||
shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0);
|
||||
@ -225,6 +261,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
TracksInfo.EMPTY,
|
||||
/* info= */ null);
|
||||
period = new Timeline.Period();
|
||||
window = new Timeline.Window();
|
||||
permanentAvailableCommands =
|
||||
new Commands.Builder()
|
||||
.addAll(
|
||||
@ -258,11 +295,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
playbackInfoUpdate ->
|
||||
playbackInfoUpdateHandler.post(() -> handlePlaybackInfo(playbackInfoUpdate));
|
||||
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
|
||||
if (analyticsCollector != null) {
|
||||
analyticsCollector.setPlayer(playerForListeners, applicationLooper);
|
||||
addListener(analyticsCollector);
|
||||
bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector);
|
||||
}
|
||||
analyticsCollector.setPlayer(wrappingPlayer, applicationLooper);
|
||||
addListener(analyticsCollector);
|
||||
bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector);
|
||||
PlayerId playerId = Util.SDK_INT < 31 ? new PlayerId() : Api31.createPlayerId();
|
||||
internalPlayer =
|
||||
new ExoPlayerImplInternal(
|
||||
@ -310,7 +345,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return internalPlayer.getPlaybackLooper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Looper getApplicationLooper() {
|
||||
return applicationLooper;
|
||||
}
|
||||
@ -319,16 +353,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
addEventListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
removeEventListener(listener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Register deprecated EventListener.
|
||||
public void addEventListener(Player.EventListener eventListener) {
|
||||
listeners.add(eventListener);
|
||||
@ -347,24 +375,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
audioOffloadListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Commands getAvailableCommands() {
|
||||
return availableCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
@State
|
||||
public int getPlaybackState() {
|
||||
return playbackInfo.playbackState;
|
||||
}
|
||||
|
||||
@Override
|
||||
@PlaybackSuppressionReason
|
||||
public int getPlaybackSuppressionReason() {
|
||||
return playbackInfo.playbackSuppressionReason;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ExoPlaybackException getPlayerError() {
|
||||
return playbackInfo.playbackError;
|
||||
@ -376,7 +400,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
prepare();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
if (playbackInfo.playbackState != Player.STATE_IDLE) {
|
||||
return;
|
||||
@ -384,7 +407,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
PlaybackInfo playbackInfo = this.playbackInfo.copyWithPlaybackError(null);
|
||||
playbackInfo =
|
||||
playbackInfo.copyWithPlaybackState(
|
||||
playbackInfo.timeline.isEmpty() ? Player.STATE_ENDED : Player.STATE_BUFFERING);
|
||||
playbackInfo.timeline.isEmpty() ? STATE_ENDED : STATE_BUFFERING);
|
||||
// Trigger internal prepare first before updating the playback info and notifying external
|
||||
// listeners to ensure that new operations issued in the listener notifications reach the
|
||||
// player after this prepare. The internal player can't change the playback info immediately
|
||||
@ -421,12 +444,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
prepare();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
|
||||
setMediaSources(createMediaSources(mediaItems), resetPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs) {
|
||||
setMediaSources(createMediaSources(mediaItems), startIndex, startPositionMs);
|
||||
}
|
||||
@ -462,7 +483,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
mediaSources, startWindowIndex, startPositionMs, /* resetToDefaultPosition= */ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMediaItems(int index, List<MediaItem> mediaItems) {
|
||||
index = min(index, mediaSourceHolderSnapshots.size());
|
||||
addMediaSources(index, createMediaSources(mediaItems));
|
||||
@ -503,7 +523,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMediaItems(int fromIndex, int toIndex) {
|
||||
toIndex = min(toIndex, mediaSourceHolderSnapshots.size());
|
||||
PlaybackInfo newPlaybackInfo = removeMediaItemsInternal(fromIndex, toIndex);
|
||||
@ -515,12 +534,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||
/* seekProcessed= */ false,
|
||||
positionDiscontinuity,
|
||||
Player.DISCONTINUITY_REASON_REMOVE,
|
||||
DISCONTINUITY_REASON_REMOVE,
|
||||
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) {
|
||||
Assertions.checkArgument(
|
||||
fromIndex >= 0
|
||||
@ -571,14 +589,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayWhenReady(boolean playWhenReady) {
|
||||
setPlayWhenReady(
|
||||
playWhenReady,
|
||||
PLAYBACK_SUPPRESSION_REASON_NONE,
|
||||
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST);
|
||||
}
|
||||
|
||||
public void setPauseAtEndOfMediaItems(boolean pauseAtEndOfMediaItems) {
|
||||
if (this.pauseAtEndOfMediaItems == pauseAtEndOfMediaItems) {
|
||||
return;
|
||||
@ -614,12 +624,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getPlayWhenReady() {
|
||||
return playbackInfo.playWhenReady;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRepeatMode(@RepeatMode int repeatMode) {
|
||||
if (this.repeatMode != repeatMode) {
|
||||
this.repeatMode = repeatMode;
|
||||
@ -631,12 +639,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @RepeatMode int getRepeatMode() {
|
||||
@RepeatMode
|
||||
public int getRepeatMode() {
|
||||
return repeatMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
|
||||
if (this.shuffleModeEnabled != shuffleModeEnabled) {
|
||||
this.shuffleModeEnabled = shuffleModeEnabled;
|
||||
@ -649,17 +656,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getShuffleModeEnabled() {
|
||||
return shuffleModeEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoading() {
|
||||
return playbackInfo.isLoading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekTo(int mediaItemIndex, long positionMs) {
|
||||
Timeline timeline = playbackInfo.timeline;
|
||||
if (mediaItemIndex < 0
|
||||
@ -680,7 +684,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
@Player.State
|
||||
int newPlaybackState =
|
||||
getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : Player.STATE_BUFFERING;
|
||||
getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : STATE_BUFFERING;
|
||||
int oldMaskingMediaItemIndex = getCurrentMediaItemIndex();
|
||||
PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackState(newPlaybackState);
|
||||
newPlaybackInfo =
|
||||
@ -700,22 +704,18 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
oldMaskingMediaItemIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeekBackIncrement() {
|
||||
return seekBackIncrementMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeekForwardIncrement() {
|
||||
return seekForwardIncrementMs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxSeekToPreviousPosition() {
|
||||
return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||
if (playbackParameters == null) {
|
||||
playbackParameters = PlaybackParameters.DEFAULT;
|
||||
@ -737,7 +737,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlaybackParameters getPlaybackParameters() {
|
||||
return playbackInfo.playbackParameters;
|
||||
}
|
||||
@ -770,13 +769,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
stop(/* reset= */ false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void stop(boolean reset) {
|
||||
stop(reset, /* error= */ null);
|
||||
}
|
||||
@ -819,7 +811,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
Log.i(
|
||||
TAG,
|
||||
@ -844,9 +835,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
listeners.release();
|
||||
playbackInfoUpdateHandler.removeCallbacksAndMessages(null);
|
||||
if (analyticsCollector != null) {
|
||||
bandwidthMeter.removeEventListener(analyticsCollector);
|
||||
}
|
||||
bandwidthMeter.removeEventListener(analyticsCollector);
|
||||
playbackInfo = playbackInfo.copyWithPlaybackState(Player.STATE_IDLE);
|
||||
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(playbackInfo.periodId);
|
||||
playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
|
||||
@ -863,7 +852,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
internalPlayer.getPlaybackLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPeriodIndex() {
|
||||
if (playbackInfo.timeline.isEmpty()) {
|
||||
return maskingPeriodIndex;
|
||||
@ -872,13 +860,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentMediaItemIndex() {
|
||||
int currentWindowIndex = getCurrentWindowIndexInternal();
|
||||
return currentWindowIndex == C.INDEX_UNSET ? 0 : currentWindowIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
if (isPlayingAd()) {
|
||||
MediaPeriodId periodId = playbackInfo.periodId;
|
||||
@ -889,12 +875,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return getContentDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
private long getContentDuration() {
|
||||
Timeline timeline = getCurrentTimeline();
|
||||
return timeline.isEmpty()
|
||||
? C.TIME_UNSET
|
||||
: timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
|
||||
}
|
||||
|
||||
public long getCurrentPosition() {
|
||||
return Util.usToMs(getCurrentPositionUsInternal(playbackInfo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBufferedPosition() {
|
||||
if (isPlayingAd()) {
|
||||
return playbackInfo.loadingMediaPeriodId.equals(playbackInfo.periodId)
|
||||
@ -904,27 +895,22 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return getContentBufferedPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalBufferedDuration() {
|
||||
return Util.usToMs(playbackInfo.totalBufferedDurationUs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayingAd() {
|
||||
return playbackInfo.periodId.isAd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentAdGroupIndex() {
|
||||
return isPlayingAd() ? playbackInfo.periodId.adGroupIndex : C.INDEX_UNSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentAdIndexInAdGroup() {
|
||||
return isPlayingAd() ? playbackInfo.periodId.adIndexInAdGroup : C.INDEX_UNSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentPosition() {
|
||||
if (isPlayingAd()) {
|
||||
playbackInfo.timeline.getPeriodByUid(playbackInfo.periodId.periodUid, period);
|
||||
@ -939,7 +925,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentBufferedPosition() {
|
||||
if (playbackInfo.timeline.isEmpty()) {
|
||||
return maskingWindowPositionMs;
|
||||
@ -971,32 +956,26 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
return renderers[index].getTrackType();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TrackSelector getTrackSelector() {
|
||||
return trackSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackGroupArray getCurrentTrackGroups() {
|
||||
return playbackInfo.trackGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackSelectionArray getCurrentTrackSelections() {
|
||||
return new TrackSelectionArray(playbackInfo.trackSelectorResult.selections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TracksInfo getCurrentTracksInfo() {
|
||||
return playbackInfo.trackSelectorResult.tracksInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackSelectionParameters getTrackSelectionParameters() {
|
||||
return trackSelector.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
|
||||
if (!trackSelector.isSetParametersSupported()
|
||||
|| parameters.equals(trackSelector.getParameters())) {
|
||||
@ -1008,7 +987,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
listener -> listener.onTrackSelectionParametersChanged(parameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaMetadata getMediaMetadata() {
|
||||
return mediaMetadata;
|
||||
}
|
||||
@ -1027,12 +1005,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
EVENT_MEDIA_METADATA_CHANGED, listener -> listener.onMediaMetadataChanged(mediaMetadata));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaMetadata getPlaylistMetadata() {
|
||||
return playlistMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaylistMetadata(MediaMetadata playlistMetadata) {
|
||||
checkNotNull(playlistMetadata);
|
||||
if (playlistMetadata.equals(this.playlistMetadata)) {
|
||||
@ -1044,109 +1020,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
listener -> listener.onPlaylistMetadataChanged(this.playlistMetadata));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
return playbackInfo.timeline;
|
||||
}
|
||||
|
||||
/** This method is not supported and returns {@link AudioAttributes#DEFAULT}. */
|
||||
@Override
|
||||
public AudioAttributes getAudioAttributes() {
|
||||
return AudioAttributes.DEFAULT;
|
||||
}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setVolume(float volume) {}
|
||||
|
||||
/** This method is not supported and returns 1. */
|
||||
@Override
|
||||
public float getVolume() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void clearVideoSurface() {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void clearVideoSurface(@Nullable Surface surface) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setVideoSurface(@Nullable Surface surface) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void clearVideoSurfaceView(@Nullable SurfaceView surfaceView) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setVideoTextureView(@Nullable TextureView textureView) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void clearVideoTextureView(@Nullable TextureView textureView) {}
|
||||
|
||||
/** This method is not supported and returns {@link VideoSize#UNKNOWN}. */
|
||||
@Override
|
||||
public VideoSize getVideoSize() {
|
||||
return VideoSize.UNKNOWN;
|
||||
}
|
||||
|
||||
/** This method is not supported and returns an empty list. */
|
||||
@Override
|
||||
public ImmutableList<Cue> getCurrentCues() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@link DeviceInfo#UNKNOWN}. */
|
||||
@Override
|
||||
public DeviceInfo getDeviceInfo() {
|
||||
return DeviceInfo.UNKNOWN;
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@code 0}. */
|
||||
@Override
|
||||
public int getDeviceVolume() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** This method is not supported and always returns {@link false}. */
|
||||
@Override
|
||||
public boolean isDeviceMuted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setDeviceVolume(int volume) {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void increaseDeviceVolume() {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void decreaseDeviceVolume() {}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setDeviceMuted(boolean muted) {}
|
||||
|
||||
private int getCurrentWindowIndexInternal() {
|
||||
if (playbackInfo.timeline.isEmpty()) {
|
||||
return maskingWindowIndex;
|
||||
@ -1329,7 +1206,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
if (metadataChanged) {
|
||||
final MediaMetadata finalMediaMetadata = mediaMetadata;
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_MEDIA_METADATA_CHANGED,
|
||||
EVENT_MEDIA_METADATA_CHANGED,
|
||||
listener -> listener.onMediaMetadataChanged(finalMediaMetadata));
|
||||
}
|
||||
if (previousPlaybackInfo.isLoading != newPlaybackInfo.isLoading) {
|
||||
@ -1537,7 +1414,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
private void updateAvailableCommands() {
|
||||
Commands previousAvailableCommands = availableCommands;
|
||||
availableCommands = getAvailableCommands(permanentAvailableCommands);
|
||||
availableCommands = Util.getAvailableCommands(wrappingPlayer, permanentAvailableCommands);
|
||||
if (!availableCommands.equals(previousAvailableCommands)) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||
@ -1599,7 +1476,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||
/* seekProcessed= */ false,
|
||||
/* positionDiscontinuity= */ positionDiscontinuity,
|
||||
Player.DISCONTINUITY_REASON_REMOVE,
|
||||
DISCONTINUITY_REASON_REMOVE,
|
||||
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
||||
/* ignored */ C.INDEX_UNSET);
|
||||
}
|
||||
@ -1838,12 +1715,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
* #onMetadata(Metadata)}) sources.
|
||||
*/
|
||||
private MediaMetadata buildUpdatedMediaMetadata() {
|
||||
@Nullable MediaItem mediaItem = getCurrentMediaItem();
|
||||
|
||||
if (mediaItem == null) {
|
||||
Timeline timeline = getCurrentTimeline();
|
||||
if (timeline.isEmpty()) {
|
||||
return staticAndDynamicMediaMetadata;
|
||||
}
|
||||
|
||||
MediaItem mediaItem = timeline.getWindow(getCurrentMediaItemIndex(), window).mediaItem;
|
||||
// MediaItem metadata is prioritized over metadata within the media.
|
||||
return staticAndDynamicMediaMetadata.buildUpon().populate(mediaItem.mediaMetadata).build();
|
||||
}
|
||||
|
@ -1362,7 +1362,6 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TrackSelector getTrackSelector() {
|
||||
verifyApplicationThread();
|
||||
return player.getTrackSelector();
|
||||
|
Loading…
x
Reference in New Issue
Block a user