Commit 7b552d77 by tonihei Committed by Oliver Woodman

Move common init steps into SimpleExoPlayer builder.

Some player setup steps that are likely to be only done once
should be moved into the Builder so that player setup can use
a consistent style (builder vs setters).

This also prevents some threading warning issues when the player
is built on a background thread (e.g. for dependency injection
frameworks) and setters can't be used due to threading restrictions.

PiperOrigin-RevId: 311487224
parent ba5871dd
......@@ -7,6 +7,8 @@
* Added `TextComponent.getCurrentCues` because the current cues are no
longer forwarded to a new `TextOutput` in `SimpleExoPlayer`
automatically.
* Add additional options to `SimpleExoPlayer.Builder` that were previously
only accessible via setters.
* Add opt-in to verify correct thread usage with
`SimpleExoPlayer.setThrowsWhenUsingWrongThread(true)`
([#4463](https://github.com/google/ExoPlayer/issues/4463)).
......
......@@ -146,6 +146,8 @@ public interface ExoPlayer extends Player {
private Looper looper;
@Nullable private AnalyticsCollector analyticsCollector;
private boolean useLazyPreparation;
private SeekParameters seekParameters;
private boolean pauseAtEndOfMediaItems;
private boolean buildCalled;
private long releaseTimeoutMs;
......@@ -166,6 +168,8 @@ public interface ExoPlayer extends Player {
* Looper}
* <li>{@link AnalyticsCollector}: {@link AnalyticsCollector} with {@link Clock#DEFAULT}
* <li>{@code useLazyPreparation}: {@code true}
* <li>{@link SeekParameters}: {@link SeekParameters#DEFAULT}
* <li>{@code pauseAtEndOfMediaItems}: {@code false}
* <li>{@link Clock}: {@link Clock#DEFAULT}
* </ul>
*
......@@ -178,50 +182,37 @@ public interface ExoPlayer extends Player {
new DefaultTrackSelector(context),
DefaultMediaSourceFactory.newInstance(context),
new DefaultLoadControl(),
DefaultBandwidthMeter.getSingletonInstance(context),
Util.getLooper(),
/* analyticsCollector= */ null,
/* useLazyPreparation= */ true,
Clock.DEFAULT);
DefaultBandwidthMeter.getSingletonInstance(context));
}
/**
* Creates a builder with the specified custom components.
*
* <p>Note that this constructor is only useful if you try to ensure that ExoPlayer's default
* components can be removed by ProGuard or R8. For most components except renderers, there is
* only a marginal benefit of doing that.
* <p>Note that this constructor is only useful to try and ensure that ExoPlayer's default
* components can be removed by ProGuard or R8.
*
* @param renderers The {@link Renderer Renderers} to be used by the player.
* @param trackSelector A {@link TrackSelector}.
* @param mediaSourceFactory A {@link MediaSourceFactory}.
* @param loadControl A {@link LoadControl}.
* @param bandwidthMeter A {@link BandwidthMeter}.
* @param looper A {@link Looper} that must be used for all calls to the player.
* @param analyticsCollector An {@link AnalyticsCollector}.
* @param useLazyPreparation Whether media sources should be initialized lazily.
* @param clock A {@link Clock}. Should always be {@link Clock#DEFAULT}.
*/
public Builder(
Renderer[] renderers,
TrackSelector trackSelector,
MediaSourceFactory mediaSourceFactory,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
Looper looper,
@Nullable AnalyticsCollector analyticsCollector,
boolean useLazyPreparation,
Clock clock) {
BandwidthMeter bandwidthMeter) {
Assertions.checkArgument(renderers.length > 0);
this.renderers = renderers;
this.trackSelector = trackSelector;
this.mediaSourceFactory = mediaSourceFactory;
this.loadControl = loadControl;
this.bandwidthMeter = bandwidthMeter;
this.looper = looper;
this.analyticsCollector = analyticsCollector;
this.useLazyPreparation = useLazyPreparation;
this.clock = clock;
looper = Util.getLooper();
useLazyPreparation = true;
seekParameters = SeekParameters.DEFAULT;
clock = Clock.DEFAULT;
}
/**
......@@ -348,6 +339,37 @@ public interface ExoPlayer extends Player {
}
/**
* Sets the parameters that control how seek operations are performed.
*
* @param seekParameters The {@link SeekParameters}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setSeekParameters(SeekParameters seekParameters) {
Assertions.checkState(!buildCalled);
this.seekParameters = seekParameters;
return this;
}
/**
* Sets whether to pause playback at the end of each media item.
*
* <p>This means the player will pause at the end of each window in the current {@link
* #getCurrentTimeline() timeline}. Listeners will be informed by a call to {@link
* Player.EventListener#onPlayWhenReadyChanged(boolean, int)} with the reason {@link
* Player#PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM} when this happens.
*
* @param pauseAtEndOfMediaItems Whether to pause playback at the end of each media item.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setPauseAtEndOfMediaItems(boolean pauseAtEndOfMediaItems) {
Assertions.checkState(!buildCalled);
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
return this;
}
/**
* Sets the {@link Clock} that will be used by the player. Should only be set for testing
* purposes.
*
......@@ -379,6 +401,8 @@ public interface ExoPlayer extends Player {
bandwidthMeter,
analyticsCollector,
useLazyPreparation,
seekParameters,
pauseAtEndOfMediaItems,
clock,
looper);
......
......@@ -258,6 +258,8 @@ public final class ExoPlayerFactory {
bandwidthMeter,
/* analyticsCollector= */ null,
/* useLazyPreparation= */ true,
SeekParameters.DEFAULT,
/* pauseAtEndOfMediaItems= */ false,
Clock.DEFAULT,
applicationLooper);
}
......
......@@ -109,6 +109,8 @@ import java.util.concurrent.TimeoutException;
* @param useLazyPreparation Whether playlist items are prepared lazily. If false, all manifest
* 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 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.
......@@ -122,6 +124,8 @@ import java.util.concurrent.TimeoutException;
BandwidthMeter bandwidthMeter,
@Nullable AnalyticsCollector analyticsCollector,
boolean useLazyPreparation,
SeekParameters seekParameters,
boolean pauseAtEndOfMediaItems,
Clock clock,
Looper applicationLooper) {
Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " ["
......@@ -131,6 +135,8 @@ import java.util.concurrent.TimeoutException;
this.trackSelector = checkNotNull(trackSelector);
this.mediaSourceFactory = mediaSourceFactory;
this.useLazyPreparation = useLazyPreparation;
this.seekParameters = seekParameters;
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
repeatMode = Player.REPEAT_MODE_OFF;
listeners = new CopyOnWriteArrayList<>();
mediaSourceHolders = new ArrayList<>();
......@@ -142,7 +148,6 @@ import java.util.concurrent.TimeoutException;
null);
period = new Timeline.Period();
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
seekParameters = SeekParameters.DEFAULT;
maskingWindowIndex = C.INDEX_UNSET;
applicationHandler =
new Handler(applicationLooper) {
......@@ -166,6 +171,8 @@ import java.util.concurrent.TimeoutException;
repeatMode,
shuffleModeEnabled,
analyticsCollector,
seekParameters,
pauseAtEndOfMediaItems,
applicationHandler,
clock);
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
......
......@@ -146,6 +146,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
@Player.RepeatMode int repeatMode,
boolean shuffleModeEnabled,
@Nullable AnalyticsCollector analyticsCollector,
SeekParameters seekParameters,
boolean pauseAtEndOfWindow,
Handler eventHandler,
Clock clock) {
this.renderers = renderers;
......@@ -155,6 +157,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
this.bandwidthMeter = bandwidthMeter;
this.repeatMode = repeatMode;
this.shuffleModeEnabled = shuffleModeEnabled;
this.seekParameters = seekParameters;
this.pauseAtEndOfWindow = pauseAtEndOfWindow;
this.eventHandler = eventHandler;
this.clock = clock;
this.queue = new MediaPeriodQueue();
......@@ -162,7 +166,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
backBufferDurationUs = loadControl.getBackBufferDurationUs();
retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe();
seekParameters = SeekParameters.DEFAULT;
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo);
rendererCapabilities = new RendererCapabilities[renderers.length];
......
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