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() {
|
private void updateAvailableCommandsAndNotifyIfChanged() {
|
||||||
Commands previousAvailableCommands = availableCommands;
|
Commands previousAvailableCommands = availableCommands;
|
||||||
availableCommands = getAvailableCommands(PERMANENT_AVAILABLE_COMMANDS);
|
availableCommands = Util.getAvailableCommands(/* player= */ this, PERMANENT_AVAILABLE_COMMANDS);
|
||||||
if (!availableCommands.equals(previousAvailableCommands)) {
|
if (!availableCommands.equals(previousAvailableCommands)) {
|
||||||
listeners.queueEvent(
|
listeners.queueEvent(
|
||||||
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||||
|
@ -384,37 +384,6 @@ public abstract class BasePlayer implements Player {
|
|||||||
: timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
|
: 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
|
@RepeatMode
|
||||||
private int getRepeatModeForNavigation() {
|
private int getRepeatModeForNavigation() {
|
||||||
@RepeatMode int repeatMode = getRepeatMode();
|
@RepeatMode int repeatMode = getRepeatMode();
|
||||||
|
@ -16,6 +16,15 @@
|
|||||||
package androidx.media3.common.util;
|
package androidx.media3.common.util;
|
||||||
|
|
||||||
import static android.content.Context.UI_MODE_SERVICE;
|
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 androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static java.lang.Math.abs;
|
import static java.lang.Math.abs;
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
@ -64,6 +73,8 @@ import androidx.media3.common.MediaLibraryInfo;
|
|||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.PlaybackException;
|
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.Ascii;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import java.io.ByteArrayOutputStream;
|
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
|
@Nullable
|
||||||
private static String getSystemProperty(String name) {
|
private static String getSystemProperty(String name) {
|
||||||
try {
|
try {
|
||||||
|
@ -15,6 +15,39 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer;
|
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.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Util.castNonNull;
|
import static androidx.media3.common.util.Util.castNonNull;
|
||||||
@ -26,17 +59,10 @@ import android.media.metrics.LogSessionId;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Pair;
|
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.DoNotInline;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.media3.common.AudioAttributes;
|
|
||||||
import androidx.media3.common.BasePlayer;
|
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.DeviceInfo;
|
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.IllegalSeekPositionException;
|
import androidx.media3.common.IllegalSeekPositionException;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
@ -46,14 +72,23 @@ import androidx.media3.common.Metadata;
|
|||||||
import androidx.media3.common.PlaybackException;
|
import androidx.media3.common.PlaybackException;
|
||||||
import androidx.media3.common.PlaybackParameters;
|
import androidx.media3.common.PlaybackParameters;
|
||||||
import androidx.media3.common.Player;
|
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.Timeline;
|
||||||
import androidx.media3.common.TrackGroup;
|
import androidx.media3.common.TrackGroup;
|
||||||
import androidx.media3.common.TrackGroupArray;
|
import androidx.media3.common.TrackGroupArray;
|
||||||
import androidx.media3.common.TrackSelectionArray;
|
import androidx.media3.common.TrackSelectionArray;
|
||||||
import androidx.media3.common.TrackSelectionParameters;
|
import androidx.media3.common.TrackSelectionParameters;
|
||||||
import androidx.media3.common.TracksInfo;
|
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.Assertions;
|
||||||
import androidx.media3.common.util.Clock;
|
import androidx.media3.common.util.Clock;
|
||||||
import androidx.media3.common.util.HandlerWrapper;
|
import androidx.media3.common.util.HandlerWrapper;
|
||||||
@ -78,8 +113,8 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
/** An {@link ExoPlayer} implementation. */
|
/** A helper class for the {@link SimpleExoPlayer} implementation of {@link ExoPlayer}. */
|
||||||
/* package */ final class ExoPlayerImpl extends BasePlayer {
|
/* package */ final class ExoPlayerImpl {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MediaLibraryInfo.registerModule("media3.exoplayer");
|
MediaLibraryInfo.registerModule("media3.exoplayer");
|
||||||
@ -97,6 +132,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* package */ final TrackSelectorResult emptyTrackSelectorResult;
|
/* package */ final TrackSelectorResult emptyTrackSelectorResult;
|
||||||
/* package */ final Commands permanentAvailableCommands;
|
/* package */ final Commands permanentAvailableCommands;
|
||||||
|
|
||||||
|
private final Player wrappingPlayer;
|
||||||
private final Renderer[] renderers;
|
private final Renderer[] renderers;
|
||||||
private final TrackSelector trackSelector;
|
private final TrackSelector trackSelector;
|
||||||
private final HandlerWrapper playbackInfoUpdateHandler;
|
private final HandlerWrapper playbackInfoUpdateHandler;
|
||||||
@ -105,10 +141,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
private final ListenerSet<Player.EventListener> listeners;
|
private final ListenerSet<Player.EventListener> listeners;
|
||||||
private final CopyOnWriteArraySet<AudioOffloadListener> audioOffloadListeners;
|
private final CopyOnWriteArraySet<AudioOffloadListener> audioOffloadListeners;
|
||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
|
private final Timeline.Window window;
|
||||||
private final List<MediaSourceHolderSnapshot> mediaSourceHolderSnapshots;
|
private final List<MediaSourceHolderSnapshot> mediaSourceHolderSnapshots;
|
||||||
private final boolean useLazyPreparation;
|
private final boolean useLazyPreparation;
|
||||||
private final MediaSourceFactory mediaSourceFactory;
|
private final MediaSourceFactory mediaSourceFactory;
|
||||||
@Nullable private final AnalyticsCollector analyticsCollector;
|
private final AnalyticsCollector analyticsCollector;
|
||||||
private final Looper applicationLooper;
|
private final Looper applicationLooper;
|
||||||
private final BandwidthMeter bandwidthMeter;
|
private final BandwidthMeter bandwidthMeter;
|
||||||
private final long seekBackIncrementMs;
|
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
|
* loads and other initial preparation steps happen immediately. If true, these initial
|
||||||
* preparations are triggered only when the player starts buffering the media.
|
* preparations are triggered only when the player starts buffering the media.
|
||||||
* @param seekParameters The {@link SeekParameters}.
|
* @param seekParameters The {@link SeekParameters}.
|
||||||
* @param seekBackIncrementMs The {@link #seekBack()} increment in milliseconds.
|
* @param seekBackIncrementMs The seek back increment in milliseconds.
|
||||||
* @param seekForwardIncrementMs The {@link #seekForward()} increment in milliseconds.
|
* @param seekForwardIncrementMs The seek forward increment in milliseconds.
|
||||||
* @param livePlaybackSpeedControl The {@link LivePlaybackSpeedControl}.
|
* @param livePlaybackSpeedControl The {@link LivePlaybackSpeedControl}.
|
||||||
* @param releaseTimeoutMs The timeout for calls to {@link #release()} in milliseconds.
|
* @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 pauseAtEndOfMediaItems Whether to pause playback at the end of each media item.
|
||||||
* @param clock The {@link Clock}.
|
* @param clock The {@link Clock}.
|
||||||
* @param applicationLooper The {@link Looper} that must be used for all calls to the player and
|
* @param applicationLooper The {@link Looper} that must be used for all calls to the player and
|
||||||
* which is used to call listeners on.
|
* which is used to call listeners on.
|
||||||
* @param wrappingPlayer The {@link Player} wrapping this one if applicable. This player instance
|
* @param wrappingPlayer The {@link Player} using this class.
|
||||||
* should be used for all externally visible callbacks.
|
|
||||||
* @param additionalPermanentAvailableCommands The {@link Commands} that are permanently available
|
* @param additionalPermanentAvailableCommands The {@link Commands} that are permanently available
|
||||||
* in the wrapping player but that are not in this player.
|
* in the wrapping player but that are not in this player.
|
||||||
*/
|
*/
|
||||||
@ -174,7 +210,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
MediaSourceFactory mediaSourceFactory,
|
MediaSourceFactory mediaSourceFactory,
|
||||||
LoadControl loadControl,
|
LoadControl loadControl,
|
||||||
BandwidthMeter bandwidthMeter,
|
BandwidthMeter bandwidthMeter,
|
||||||
@Nullable AnalyticsCollector analyticsCollector,
|
AnalyticsCollector analyticsCollector,
|
||||||
boolean useLazyPreparation,
|
boolean useLazyPreparation,
|
||||||
SeekParameters seekParameters,
|
SeekParameters seekParameters,
|
||||||
long seekBackIncrementMs,
|
long seekBackIncrementMs,
|
||||||
@ -184,7 +220,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
boolean pauseAtEndOfMediaItems,
|
boolean pauseAtEndOfMediaItems,
|
||||||
Clock clock,
|
Clock clock,
|
||||||
Looper applicationLooper,
|
Looper applicationLooper,
|
||||||
@Nullable Player wrappingPlayer,
|
Player wrappingPlayer,
|
||||||
Commands additionalPermanentAvailableCommands) {
|
Commands additionalPermanentAvailableCommands) {
|
||||||
Log.i(
|
Log.i(
|
||||||
TAG,
|
TAG,
|
||||||
@ -208,13 +244,13 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
|
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
|
||||||
this.applicationLooper = applicationLooper;
|
this.applicationLooper = applicationLooper;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
|
this.wrappingPlayer = wrappingPlayer;
|
||||||
repeatMode = Player.REPEAT_MODE_OFF;
|
repeatMode = Player.REPEAT_MODE_OFF;
|
||||||
Player playerForListeners = wrappingPlayer != null ? wrappingPlayer : this;
|
|
||||||
listeners =
|
listeners =
|
||||||
new ListenerSet<>(
|
new ListenerSet<>(
|
||||||
applicationLooper,
|
applicationLooper,
|
||||||
clock,
|
clock,
|
||||||
(listener, flags) -> listener.onEvents(playerForListeners, new Events(flags)));
|
(listener, flags) -> listener.onEvents(wrappingPlayer, new Events(flags)));
|
||||||
audioOffloadListeners = new CopyOnWriteArraySet<>();
|
audioOffloadListeners = new CopyOnWriteArraySet<>();
|
||||||
mediaSourceHolderSnapshots = new ArrayList<>();
|
mediaSourceHolderSnapshots = new ArrayList<>();
|
||||||
shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0);
|
shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */ 0);
|
||||||
@ -225,6 +261,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
TracksInfo.EMPTY,
|
TracksInfo.EMPTY,
|
||||||
/* info= */ null);
|
/* info= */ null);
|
||||||
period = new Timeline.Period();
|
period = new Timeline.Period();
|
||||||
|
window = new Timeline.Window();
|
||||||
permanentAvailableCommands =
|
permanentAvailableCommands =
|
||||||
new Commands.Builder()
|
new Commands.Builder()
|
||||||
.addAll(
|
.addAll(
|
||||||
@ -258,11 +295,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
playbackInfoUpdate ->
|
playbackInfoUpdate ->
|
||||||
playbackInfoUpdateHandler.post(() -> handlePlaybackInfo(playbackInfoUpdate));
|
playbackInfoUpdateHandler.post(() -> handlePlaybackInfo(playbackInfoUpdate));
|
||||||
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
|
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
|
||||||
if (analyticsCollector != null) {
|
analyticsCollector.setPlayer(wrappingPlayer, applicationLooper);
|
||||||
analyticsCollector.setPlayer(playerForListeners, applicationLooper);
|
|
||||||
addListener(analyticsCollector);
|
addListener(analyticsCollector);
|
||||||
bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector);
|
bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector);
|
||||||
}
|
|
||||||
PlayerId playerId = Util.SDK_INT < 31 ? new PlayerId() : Api31.createPlayerId();
|
PlayerId playerId = Util.SDK_INT < 31 ? new PlayerId() : Api31.createPlayerId();
|
||||||
internalPlayer =
|
internalPlayer =
|
||||||
new ExoPlayerImplInternal(
|
new ExoPlayerImplInternal(
|
||||||
@ -310,7 +345,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return internalPlayer.getPlaybackLooper();
|
return internalPlayer.getPlaybackLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Looper getApplicationLooper() {
|
public Looper getApplicationLooper() {
|
||||||
return applicationLooper;
|
return applicationLooper;
|
||||||
}
|
}
|
||||||
@ -319,16 +353,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return clock;
|
return clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener(Listener listener) {
|
public void addListener(Listener listener) {
|
||||||
addEventListener(listener);
|
addEventListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener(Listener listener) {
|
|
||||||
removeEventListener(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation") // Register deprecated EventListener.
|
@SuppressWarnings("deprecation") // Register deprecated EventListener.
|
||||||
public void addEventListener(Player.EventListener eventListener) {
|
public void addEventListener(Player.EventListener eventListener) {
|
||||||
listeners.add(eventListener);
|
listeners.add(eventListener);
|
||||||
@ -347,24 +375,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
audioOffloadListeners.remove(listener);
|
audioOffloadListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Commands getAvailableCommands() {
|
public Commands getAvailableCommands() {
|
||||||
return availableCommands;
|
return availableCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@State
|
@State
|
||||||
public int getPlaybackState() {
|
public int getPlaybackState() {
|
||||||
return playbackInfo.playbackState;
|
return playbackInfo.playbackState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@PlaybackSuppressionReason
|
@PlaybackSuppressionReason
|
||||||
public int getPlaybackSuppressionReason() {
|
public int getPlaybackSuppressionReason() {
|
||||||
return playbackInfo.playbackSuppressionReason;
|
return playbackInfo.playbackSuppressionReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ExoPlaybackException getPlayerError() {
|
public ExoPlaybackException getPlayerError() {
|
||||||
return playbackInfo.playbackError;
|
return playbackInfo.playbackError;
|
||||||
@ -376,7 +400,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
prepare();
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void prepare() {
|
public void prepare() {
|
||||||
if (playbackInfo.playbackState != Player.STATE_IDLE) {
|
if (playbackInfo.playbackState != Player.STATE_IDLE) {
|
||||||
return;
|
return;
|
||||||
@ -384,7 +407,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
PlaybackInfo playbackInfo = this.playbackInfo.copyWithPlaybackError(null);
|
PlaybackInfo playbackInfo = this.playbackInfo.copyWithPlaybackError(null);
|
||||||
playbackInfo =
|
playbackInfo =
|
||||||
playbackInfo.copyWithPlaybackState(
|
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
|
// 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
|
// 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
|
// player after this prepare. The internal player can't change the playback info immediately
|
||||||
@ -421,12 +444,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
prepare();
|
prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
|
public void setMediaItems(List<MediaItem> mediaItems, boolean resetPosition) {
|
||||||
setMediaSources(createMediaSources(mediaItems), resetPosition);
|
setMediaSources(createMediaSources(mediaItems), resetPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs) {
|
public void setMediaItems(List<MediaItem> mediaItems, int startIndex, long startPositionMs) {
|
||||||
setMediaSources(createMediaSources(mediaItems), startIndex, startPositionMs);
|
setMediaSources(createMediaSources(mediaItems), startIndex, startPositionMs);
|
||||||
}
|
}
|
||||||
@ -462,7 +483,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
mediaSources, startWindowIndex, startPositionMs, /* resetToDefaultPosition= */ false);
|
mediaSources, startWindowIndex, startPositionMs, /* resetToDefaultPosition= */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addMediaItems(int index, List<MediaItem> mediaItems) {
|
public void addMediaItems(int index, List<MediaItem> mediaItems) {
|
||||||
index = min(index, mediaSourceHolderSnapshots.size());
|
index = min(index, mediaSourceHolderSnapshots.size());
|
||||||
addMediaSources(index, createMediaSources(mediaItems));
|
addMediaSources(index, createMediaSources(mediaItems));
|
||||||
@ -503,7 +523,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeMediaItems(int fromIndex, int toIndex) {
|
public void removeMediaItems(int fromIndex, int toIndex) {
|
||||||
toIndex = min(toIndex, mediaSourceHolderSnapshots.size());
|
toIndex = min(toIndex, mediaSourceHolderSnapshots.size());
|
||||||
PlaybackInfo newPlaybackInfo = removeMediaItemsInternal(fromIndex, toIndex);
|
PlaybackInfo newPlaybackInfo = removeMediaItemsInternal(fromIndex, toIndex);
|
||||||
@ -515,12 +534,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||||
/* seekProcessed= */ false,
|
/* seekProcessed= */ false,
|
||||||
positionDiscontinuity,
|
positionDiscontinuity,
|
||||||
Player.DISCONTINUITY_REASON_REMOVE,
|
DISCONTINUITY_REASON_REMOVE,
|
||||||
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) {
|
public void moveMediaItems(int fromIndex, int toIndex, int newFromIndex) {
|
||||||
Assertions.checkArgument(
|
Assertions.checkArgument(
|
||||||
fromIndex >= 0
|
fromIndex >= 0
|
||||||
@ -571,14 +589,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ C.INDEX_UNSET);
|
/* 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) {
|
public void setPauseAtEndOfMediaItems(boolean pauseAtEndOfMediaItems) {
|
||||||
if (this.pauseAtEndOfMediaItems == pauseAtEndOfMediaItems) {
|
if (this.pauseAtEndOfMediaItems == pauseAtEndOfMediaItems) {
|
||||||
return;
|
return;
|
||||||
@ -614,12 +624,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getPlayWhenReady() {
|
public boolean getPlayWhenReady() {
|
||||||
return playbackInfo.playWhenReady;
|
return playbackInfo.playWhenReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRepeatMode(@RepeatMode int repeatMode) {
|
public void setRepeatMode(@RepeatMode int repeatMode) {
|
||||||
if (this.repeatMode != repeatMode) {
|
if (this.repeatMode != repeatMode) {
|
||||||
this.repeatMode = repeatMode;
|
this.repeatMode = repeatMode;
|
||||||
@ -631,12 +639,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@RepeatMode
|
||||||
public @RepeatMode int getRepeatMode() {
|
public int getRepeatMode() {
|
||||||
return repeatMode;
|
return repeatMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
|
public void setShuffleModeEnabled(boolean shuffleModeEnabled) {
|
||||||
if (this.shuffleModeEnabled != shuffleModeEnabled) {
|
if (this.shuffleModeEnabled != shuffleModeEnabled) {
|
||||||
this.shuffleModeEnabled = shuffleModeEnabled;
|
this.shuffleModeEnabled = shuffleModeEnabled;
|
||||||
@ -649,17 +656,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getShuffleModeEnabled() {
|
public boolean getShuffleModeEnabled() {
|
||||||
return shuffleModeEnabled;
|
return shuffleModeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLoading() {
|
public boolean isLoading() {
|
||||||
return playbackInfo.isLoading;
|
return playbackInfo.isLoading;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void seekTo(int mediaItemIndex, long positionMs) {
|
public void seekTo(int mediaItemIndex, long positionMs) {
|
||||||
Timeline timeline = playbackInfo.timeline;
|
Timeline timeline = playbackInfo.timeline;
|
||||||
if (mediaItemIndex < 0
|
if (mediaItemIndex < 0
|
||||||
@ -680,7 +684,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
@Player.State
|
@Player.State
|
||||||
int newPlaybackState =
|
int newPlaybackState =
|
||||||
getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : Player.STATE_BUFFERING;
|
getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : STATE_BUFFERING;
|
||||||
int oldMaskingMediaItemIndex = getCurrentMediaItemIndex();
|
int oldMaskingMediaItemIndex = getCurrentMediaItemIndex();
|
||||||
PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackState(newPlaybackState);
|
PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackState(newPlaybackState);
|
||||||
newPlaybackInfo =
|
newPlaybackInfo =
|
||||||
@ -700,22 +704,18 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
oldMaskingMediaItemIndex);
|
oldMaskingMediaItemIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSeekBackIncrement() {
|
public long getSeekBackIncrement() {
|
||||||
return seekBackIncrementMs;
|
return seekBackIncrementMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getSeekForwardIncrement() {
|
public long getSeekForwardIncrement() {
|
||||||
return seekForwardIncrementMs;
|
return seekForwardIncrementMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getMaxSeekToPreviousPosition() {
|
public long getMaxSeekToPreviousPosition() {
|
||||||
return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
return C.DEFAULT_MAX_SEEK_TO_PREVIOUS_POSITION_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||||
if (playbackParameters == null) {
|
if (playbackParameters == null) {
|
||||||
playbackParameters = PlaybackParameters.DEFAULT;
|
playbackParameters = PlaybackParameters.DEFAULT;
|
||||||
@ -737,7 +737,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PlaybackParameters getPlaybackParameters() {
|
public PlaybackParameters getPlaybackParameters() {
|
||||||
return playbackInfo.playbackParameters;
|
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) {
|
public void stop(boolean reset) {
|
||||||
stop(reset, /* error= */ null);
|
stop(reset, /* error= */ null);
|
||||||
}
|
}
|
||||||
@ -819,7 +811,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {
|
public void release() {
|
||||||
Log.i(
|
Log.i(
|
||||||
TAG,
|
TAG,
|
||||||
@ -844,9 +835,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
listeners.release();
|
listeners.release();
|
||||||
playbackInfoUpdateHandler.removeCallbacksAndMessages(null);
|
playbackInfoUpdateHandler.removeCallbacksAndMessages(null);
|
||||||
if (analyticsCollector != null) {
|
|
||||||
bandwidthMeter.removeEventListener(analyticsCollector);
|
bandwidthMeter.removeEventListener(analyticsCollector);
|
||||||
}
|
|
||||||
playbackInfo = playbackInfo.copyWithPlaybackState(Player.STATE_IDLE);
|
playbackInfo = playbackInfo.copyWithPlaybackState(Player.STATE_IDLE);
|
||||||
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(playbackInfo.periodId);
|
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(playbackInfo.periodId);
|
||||||
playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
|
playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
|
||||||
@ -863,7 +852,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
internalPlayer.getPlaybackLooper());
|
internalPlayer.getPlaybackLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentPeriodIndex() {
|
public int getCurrentPeriodIndex() {
|
||||||
if (playbackInfo.timeline.isEmpty()) {
|
if (playbackInfo.timeline.isEmpty()) {
|
||||||
return maskingPeriodIndex;
|
return maskingPeriodIndex;
|
||||||
@ -872,13 +860,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentMediaItemIndex() {
|
public int getCurrentMediaItemIndex() {
|
||||||
int currentWindowIndex = getCurrentWindowIndexInternal();
|
int currentWindowIndex = getCurrentWindowIndexInternal();
|
||||||
return currentWindowIndex == C.INDEX_UNSET ? 0 : currentWindowIndex;
|
return currentWindowIndex == C.INDEX_UNSET ? 0 : currentWindowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
if (isPlayingAd()) {
|
if (isPlayingAd()) {
|
||||||
MediaPeriodId periodId = playbackInfo.periodId;
|
MediaPeriodId periodId = playbackInfo.periodId;
|
||||||
@ -889,12 +875,17 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return getContentDuration();
|
return getContentDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private long getContentDuration() {
|
||||||
|
Timeline timeline = getCurrentTimeline();
|
||||||
|
return timeline.isEmpty()
|
||||||
|
? C.TIME_UNSET
|
||||||
|
: timeline.getWindow(getCurrentMediaItemIndex(), window).getDurationMs();
|
||||||
|
}
|
||||||
|
|
||||||
public long getCurrentPosition() {
|
public long getCurrentPosition() {
|
||||||
return Util.usToMs(getCurrentPositionUsInternal(playbackInfo));
|
return Util.usToMs(getCurrentPositionUsInternal(playbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getBufferedPosition() {
|
public long getBufferedPosition() {
|
||||||
if (isPlayingAd()) {
|
if (isPlayingAd()) {
|
||||||
return playbackInfo.loadingMediaPeriodId.equals(playbackInfo.periodId)
|
return playbackInfo.loadingMediaPeriodId.equals(playbackInfo.periodId)
|
||||||
@ -904,27 +895,22 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return getContentBufferedPosition();
|
return getContentBufferedPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalBufferedDuration() {
|
public long getTotalBufferedDuration() {
|
||||||
return Util.usToMs(playbackInfo.totalBufferedDurationUs);
|
return Util.usToMs(playbackInfo.totalBufferedDurationUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPlayingAd() {
|
public boolean isPlayingAd() {
|
||||||
return playbackInfo.periodId.isAd();
|
return playbackInfo.periodId.isAd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentAdGroupIndex() {
|
public int getCurrentAdGroupIndex() {
|
||||||
return isPlayingAd() ? playbackInfo.periodId.adGroupIndex : C.INDEX_UNSET;
|
return isPlayingAd() ? playbackInfo.periodId.adGroupIndex : C.INDEX_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentAdIndexInAdGroup() {
|
public int getCurrentAdIndexInAdGroup() {
|
||||||
return isPlayingAd() ? playbackInfo.periodId.adIndexInAdGroup : C.INDEX_UNSET;
|
return isPlayingAd() ? playbackInfo.periodId.adIndexInAdGroup : C.INDEX_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getContentPosition() {
|
public long getContentPosition() {
|
||||||
if (isPlayingAd()) {
|
if (isPlayingAd()) {
|
||||||
playbackInfo.timeline.getPeriodByUid(playbackInfo.periodId.periodUid, period);
|
playbackInfo.timeline.getPeriodByUid(playbackInfo.periodId.periodUid, period);
|
||||||
@ -939,7 +925,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getContentBufferedPosition() {
|
public long getContentBufferedPosition() {
|
||||||
if (playbackInfo.timeline.isEmpty()) {
|
if (playbackInfo.timeline.isEmpty()) {
|
||||||
return maskingWindowPositionMs;
|
return maskingWindowPositionMs;
|
||||||
@ -971,32 +956,26 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
return renderers[index].getTrackType();
|
return renderers[index].getTrackType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public TrackSelector getTrackSelector() {
|
public TrackSelector getTrackSelector() {
|
||||||
return trackSelector;
|
return trackSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackGroupArray getCurrentTrackGroups() {
|
public TrackGroupArray getCurrentTrackGroups() {
|
||||||
return playbackInfo.trackGroups;
|
return playbackInfo.trackGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackSelectionArray getCurrentTrackSelections() {
|
public TrackSelectionArray getCurrentTrackSelections() {
|
||||||
return new TrackSelectionArray(playbackInfo.trackSelectorResult.selections);
|
return new TrackSelectionArray(playbackInfo.trackSelectorResult.selections);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TracksInfo getCurrentTracksInfo() {
|
public TracksInfo getCurrentTracksInfo() {
|
||||||
return playbackInfo.trackSelectorResult.tracksInfo;
|
return playbackInfo.trackSelectorResult.tracksInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TrackSelectionParameters getTrackSelectionParameters() {
|
public TrackSelectionParameters getTrackSelectionParameters() {
|
||||||
return trackSelector.getParameters();
|
return trackSelector.getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
|
public void setTrackSelectionParameters(TrackSelectionParameters parameters) {
|
||||||
if (!trackSelector.isSetParametersSupported()
|
if (!trackSelector.isSetParametersSupported()
|
||||||
|| parameters.equals(trackSelector.getParameters())) {
|
|| parameters.equals(trackSelector.getParameters())) {
|
||||||
@ -1008,7 +987,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
listener -> listener.onTrackSelectionParametersChanged(parameters));
|
listener -> listener.onTrackSelectionParametersChanged(parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MediaMetadata getMediaMetadata() {
|
public MediaMetadata getMediaMetadata() {
|
||||||
return mediaMetadata;
|
return mediaMetadata;
|
||||||
}
|
}
|
||||||
@ -1027,12 +1005,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
EVENT_MEDIA_METADATA_CHANGED, listener -> listener.onMediaMetadataChanged(mediaMetadata));
|
EVENT_MEDIA_METADATA_CHANGED, listener -> listener.onMediaMetadataChanged(mediaMetadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MediaMetadata getPlaylistMetadata() {
|
public MediaMetadata getPlaylistMetadata() {
|
||||||
return playlistMetadata;
|
return playlistMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlaylistMetadata(MediaMetadata playlistMetadata) {
|
public void setPlaylistMetadata(MediaMetadata playlistMetadata) {
|
||||||
checkNotNull(playlistMetadata);
|
checkNotNull(playlistMetadata);
|
||||||
if (playlistMetadata.equals(this.playlistMetadata)) {
|
if (playlistMetadata.equals(this.playlistMetadata)) {
|
||||||
@ -1044,109 +1020,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
listener -> listener.onPlaylistMetadataChanged(this.playlistMetadata));
|
listener -> listener.onPlaylistMetadataChanged(this.playlistMetadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Timeline getCurrentTimeline() {
|
public Timeline getCurrentTimeline() {
|
||||||
return playbackInfo.timeline;
|
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() {
|
private int getCurrentWindowIndexInternal() {
|
||||||
if (playbackInfo.timeline.isEmpty()) {
|
if (playbackInfo.timeline.isEmpty()) {
|
||||||
return maskingWindowIndex;
|
return maskingWindowIndex;
|
||||||
@ -1329,7 +1206,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
if (metadataChanged) {
|
if (metadataChanged) {
|
||||||
final MediaMetadata finalMediaMetadata = mediaMetadata;
|
final MediaMetadata finalMediaMetadata = mediaMetadata;
|
||||||
listeners.queueEvent(
|
listeners.queueEvent(
|
||||||
Player.EVENT_MEDIA_METADATA_CHANGED,
|
EVENT_MEDIA_METADATA_CHANGED,
|
||||||
listener -> listener.onMediaMetadataChanged(finalMediaMetadata));
|
listener -> listener.onMediaMetadataChanged(finalMediaMetadata));
|
||||||
}
|
}
|
||||||
if (previousPlaybackInfo.isLoading != newPlaybackInfo.isLoading) {
|
if (previousPlaybackInfo.isLoading != newPlaybackInfo.isLoading) {
|
||||||
@ -1537,7 +1414,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
|
|
||||||
private void updateAvailableCommands() {
|
private void updateAvailableCommands() {
|
||||||
Commands previousAvailableCommands = availableCommands;
|
Commands previousAvailableCommands = availableCommands;
|
||||||
availableCommands = getAvailableCommands(permanentAvailableCommands);
|
availableCommands = Util.getAvailableCommands(wrappingPlayer, permanentAvailableCommands);
|
||||||
if (!availableCommands.equals(previousAvailableCommands)) {
|
if (!availableCommands.equals(previousAvailableCommands)) {
|
||||||
listeners.queueEvent(
|
listeners.queueEvent(
|
||||||
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||||
@ -1599,7 +1476,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
|
||||||
/* seekProcessed= */ false,
|
/* seekProcessed= */ false,
|
||||||
/* positionDiscontinuity= */ positionDiscontinuity,
|
/* positionDiscontinuity= */ positionDiscontinuity,
|
||||||
Player.DISCONTINUITY_REASON_REMOVE,
|
DISCONTINUITY_REASON_REMOVE,
|
||||||
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
/* discontinuityWindowStartPositionUs= */ getCurrentPositionUsInternal(newPlaybackInfo),
|
||||||
/* ignored */ C.INDEX_UNSET);
|
/* ignored */ C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
@ -1838,12 +1715,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
* #onMetadata(Metadata)}) sources.
|
* #onMetadata(Metadata)}) sources.
|
||||||
*/
|
*/
|
||||||
private MediaMetadata buildUpdatedMediaMetadata() {
|
private MediaMetadata buildUpdatedMediaMetadata() {
|
||||||
@Nullable MediaItem mediaItem = getCurrentMediaItem();
|
Timeline timeline = getCurrentTimeline();
|
||||||
|
if (timeline.isEmpty()) {
|
||||||
if (mediaItem == null) {
|
|
||||||
return staticAndDynamicMediaMetadata;
|
return staticAndDynamicMediaMetadata;
|
||||||
}
|
}
|
||||||
|
MediaItem mediaItem = timeline.getWindow(getCurrentMediaItemIndex(), window).mediaItem;
|
||||||
// MediaItem metadata is prioritized over metadata within the media.
|
// MediaItem metadata is prioritized over metadata within the media.
|
||||||
return staticAndDynamicMediaMetadata.buildUpon().populate(mediaItem.mediaMetadata).build();
|
return staticAndDynamicMediaMetadata.buildUpon().populate(mediaItem.mediaMetadata).build();
|
||||||
}
|
}
|
||||||
|
@ -1362,7 +1362,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
|
||||||
public TrackSelector getTrackSelector() {
|
public TrackSelector getTrackSelector() {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
return player.getTrackSelector();
|
return player.getTrackSelector();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user