Move SimpleExoPlayer.Builder to ExoPlayer

- Remove ExoPlayer.Builder
- Copy SimpleExoPlayer.Builder to ExoPlayer
- Deprecate SimpleExoPlayer.Builder

PiperOrigin-RevId: 389890299
This commit is contained in:
kimvde 2021-08-10 16:28:08 +01:00 committed by Christos Tsilopoulos
parent f5d8c211f5
commit 10b4e10f43
3 changed files with 356 additions and 421 deletions

View File

@ -4,6 +4,8 @@
* Core Library:
* Move `com.google.android.exoplayer2.device.DeviceInfo` to
`com.google.android.exoplayer2.DeviceInfo`.
* Make `ExoPlayer.Builder` return a `SimpleExoPlayer` instance.
* Deprecate `SimpleExoPlayer.Builder`. Use `ExoPlayer.Builder` instead.
* Android 12 compatibility:
* Disable platform transcoding when playing content URIs on Android 12.
* Add `ExoPlayer.setVideoChangeFrameRateStrategy` to allow disabling of

View File

@ -23,6 +23,7 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
@ -33,6 +34,8 @@ import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.audio.AuxEffectInfo;
import com.google.android.exoplayer2.audio.DefaultAudioSink;
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.metadata.MetadataRenderer;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
@ -47,8 +50,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.PriorityTaskManager;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
@ -59,7 +62,7 @@ import java.util.List;
/**
* An extensible media player that plays {@link MediaSource}s. Instances can be obtained from {@link
* SimpleExoPlayer.Builder}.
* Builder}.
*
* <h2>Player components</h2>
*
@ -73,10 +76,10 @@ import java.util.List;
* <li><b>{@link MediaSource MediaSources}</b> that define the media to be played, load the media,
* and from which the loaded media can be read. MediaSources are created from {@link MediaItem
* MediaItems} by the {@link MediaSourceFactory} injected into the player {@link
* SimpleExoPlayer.Builder#setMediaSourceFactory Builder}, or can be added directly by methods
* like {@link #setMediaSource(MediaSource)}. The library provides a {@link
* DefaultMediaSourceFactory} for progressive media files, DASH, SmoothStreaming and HLS,
* which also includes functionality for side-loading subtitle files and clipping media.
* Builder#setMediaSourceFactory Builder}, or can be added directly by methods like {@link
* #setMediaSource(MediaSource)}. The library provides a {@link DefaultMediaSourceFactory} for
* progressive media files, DASH, SmoothStreaming and HLS, which also includes functionality
* for side-loading subtitle files and clipping media.
* <li><b>{@link Renderer}</b>s that render individual components of the media. The library
* provides default implementations for common media types ({@link MediaCodecVideoRenderer},
* {@link MediaCodecAudioRenderer}, {@link TextRenderer} and {@link MetadataRenderer}). A
@ -505,12 +508,6 @@ public interface ExoPlayer extends Player {
void setDeviceMuted(boolean muted);
}
/**
* The default timeout for calls to {@link #release} and {@link #setForegroundMode}, in
* milliseconds.
*/
long DEFAULT_RELEASE_TIMEOUT_MS = 500;
/**
* A listener for audio offload events.
*
@ -519,7 +516,7 @@ public interface ExoPlayer extends Player {
interface AudioOffloadListener {
/**
* Called when the player has started or stopped offload scheduling using {@link
* ExoPlayer#experimentalSetOffloadSchedulingEnabled(boolean)}.
* #experimentalSetOffloadSchedulingEnabled(boolean)}.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*/
@ -534,39 +531,28 @@ public interface ExoPlayer extends Player {
}
/**
* A builder for {@link ExoPlayer} instances.
* A builder for {@link SimpleExoPlayer} instances.
*
* <p>See {@link #Builder(Context, Renderer...)} for the list of default values.
*
* @deprecated Use {@link SimpleExoPlayer.Builder} instead.
* <p>See {@link #Builder(Context)} for the list of default values.
*/
@Deprecated
@SuppressWarnings("deprecation")
final class Builder {
private final Renderer[] renderers;
private Clock clock;
private TrackSelector trackSelector;
private MediaSourceFactory mediaSourceFactory;
private LoadControl loadControl;
private BandwidthMeter bandwidthMeter;
private Looper looper;
@Nullable private AnalyticsCollector analyticsCollector;
private boolean useLazyPreparation;
private SeekParameters seekParameters;
private boolean pauseAtEndOfMediaItems;
private long releaseTimeoutMs;
private LivePlaybackSpeedControl livePlaybackSpeedControl;
private boolean buildCalled;
private long setForegroundModeTimeoutMs;
private final SimpleExoPlayer.Builder wrappedBuilder;
/**
* Creates a builder with a list of {@link Renderer Renderers}.
* Creates a builder.
*
* <p>Use {@link #Builder(Context, RenderersFactory)}, {@link #Builder(Context,
* RenderersFactory)} or {@link #Builder(Context, RenderersFactory, ExtractorsFactory)} instead,
* if you intend to provide a custom {@link RenderersFactory} or a custom {@link
* ExtractorsFactory}. This is to ensure that ProGuard or R8 can remove ExoPlayer's {@link
* DefaultRenderersFactory} and {@link DefaultExtractorsFactory} from the APK.
*
* <p>The builder uses the following default values:
*
* <ul>
* <li>{@link RenderersFactory}: {@link DefaultRenderersFactory}
* <li>{@link TrackSelector}: {@link DefaultTrackSelector}
* <li>{@link MediaSourceFactory}: {@link DefaultMediaSourceFactory}
* <li>{@link LoadControl}: {@link DefaultLoadControl}
@ -576,23 +562,70 @@ public interface ExoPlayer extends Player {
* Looper} of the application's main thread if the current thread doesn't have a {@link
* Looper}
* <li>{@link AnalyticsCollector}: {@link AnalyticsCollector} with {@link Clock#DEFAULT}
* <li>{@link PriorityTaskManager}: {@code null} (not used)
* <li>{@link AudioAttributes}: {@link AudioAttributes#DEFAULT}, not handling audio focus
* <li>{@link C.WakeMode}: {@link C#WAKE_MODE_NONE}
* <li>{@code handleAudioBecomingNoisy}: {@code false}
* <li>{@code skipSilenceEnabled}: {@code false}
* <li>{@link C.VideoScalingMode}: {@link C#VIDEO_SCALING_MODE_DEFAULT}
* <li>{@link C.VideoChangeFrameRateStrategy}: {@link
* C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_ONLY_IF_SEAMLESS}
* <li>{@code useLazyPreparation}: {@code true}
* <li>{@link SeekParameters}: {@link SeekParameters#DEFAULT}
* <li>{@code releaseTimeoutMs}: {@link ExoPlayer#DEFAULT_RELEASE_TIMEOUT_MS}
* <li>{@code seekBackIncrementMs}: {@link C#DEFAULT_SEEK_BACK_INCREMENT_MS}
* <li>{@code seekForwardIncrementMs}: {@link C#DEFAULT_SEEK_FORWARD_INCREMENT_MS}
* <li>{@code releaseTimeoutMs}: {@link #DEFAULT_RELEASE_TIMEOUT_MS}
* <li>{@code detachSurfaceTimeoutMs}: {@link #DEFAULT_DETACH_SURFACE_TIMEOUT_MS}
* <li>{@code pauseAtEndOfMediaItems}: {@code false}
* <li>{@link Clock}: {@link Clock#DEFAULT}
* </ul>
*
* @param context A {@link Context}.
* @param renderers The {@link Renderer Renderers} to be used by the player.
*/
public Builder(Context context, Renderer... renderers) {
this(
renderers,
new DefaultTrackSelector(context),
new DefaultMediaSourceFactory(context),
new DefaultLoadControl(),
DefaultBandwidthMeter.getSingletonInstance(context));
public Builder(Context context) {
wrappedBuilder = new SimpleExoPlayer.Builder(context);
}
/**
* Creates a builder with a custom {@link RenderersFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
* player.
*/
public Builder(Context context, RenderersFactory renderersFactory) {
wrappedBuilder = new SimpleExoPlayer.Builder(context, renderersFactory);
}
/**
* Creates a builder with a custom {@link ExtractorsFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
* its container.
*/
public Builder(Context context, ExtractorsFactory extractorsFactory) {
wrappedBuilder = new SimpleExoPlayer.Builder(context, extractorsFactory);
}
/**
* Creates a builder with a custom {@link RenderersFactory} and {@link ExtractorsFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
* player.
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
* its container.
*/
public Builder(
Context context, RenderersFactory renderersFactory, ExtractorsFactory extractorsFactory) {
wrappedBuilder = new SimpleExoPlayer.Builder(context, renderersFactory, extractorsFactory);
}
/**
@ -601,44 +634,45 @@ public interface ExoPlayer extends Player {
* <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 context A {@link Context}.
* @param renderersFactory A factory for creating {@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 analyticsCollector An {@link AnalyticsCollector}.
*/
public Builder(
Renderer[] renderers,
Context context,
RenderersFactory renderersFactory,
TrackSelector trackSelector,
MediaSourceFactory mediaSourceFactory,
LoadControl loadControl,
BandwidthMeter bandwidthMeter) {
Assertions.checkArgument(renderers.length > 0);
this.renderers = renderers;
this.trackSelector = trackSelector;
this.mediaSourceFactory = mediaSourceFactory;
this.loadControl = loadControl;
this.bandwidthMeter = bandwidthMeter;
looper = Util.getCurrentOrMainLooper();
useLazyPreparation = true;
seekParameters = SeekParameters.DEFAULT;
livePlaybackSpeedControl = new DefaultLivePlaybackSpeedControl.Builder().build();
clock = Clock.DEFAULT;
releaseTimeoutMs = DEFAULT_RELEASE_TIMEOUT_MS;
BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector) {
wrappedBuilder =
new SimpleExoPlayer.Builder(
context,
renderersFactory,
trackSelector,
mediaSourceFactory,
loadControl,
bandwidthMeter,
analyticsCollector);
}
/**
* Set a limit on the time a call to {@link ExoPlayer#setForegroundMode} can spend. If a call to
* {@link ExoPlayer#setForegroundMode} takes more than {@code timeoutMs} milliseconds to
* complete, the player will raise an error via {@link Player.Listener#onPlayerError}.
* Set a limit on the time a call to {@link #setForegroundMode} can spend. If a call to {@link
* #setForegroundMode} takes more than {@code timeoutMs} milliseconds to complete, the player
* will raise an error via {@link Player.Listener#onPlayerError}.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param timeoutMs The time limit in milliseconds.
*/
public Builder experimentalSetForegroundModeTimeoutMs(long timeoutMs) {
Assertions.checkState(!buildCalled);
setForegroundModeTimeoutMs = timeoutMs;
wrappedBuilder.experimentalSetForegroundModeTimeoutMs(timeoutMs);
return this;
}
@ -650,8 +684,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setTrackSelector(TrackSelector trackSelector) {
Assertions.checkState(!buildCalled);
this.trackSelector = trackSelector;
wrappedBuilder.setTrackSelector(trackSelector);
return this;
}
@ -663,8 +696,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
Assertions.checkState(!buildCalled);
this.mediaSourceFactory = mediaSourceFactory;
wrappedBuilder.setMediaSourceFactory(mediaSourceFactory);
return this;
}
@ -676,8 +708,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setLoadControl(LoadControl loadControl) {
Assertions.checkState(!buildCalled);
this.loadControl = loadControl;
wrappedBuilder.setLoadControl(loadControl);
return this;
}
@ -689,8 +720,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) {
Assertions.checkState(!buildCalled);
this.bandwidthMeter = bandwidthMeter;
wrappedBuilder.setBandwidthMeter(bandwidthMeter);
return this;
}
@ -703,8 +733,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setLooper(Looper looper) {
Assertions.checkState(!buildCalled);
this.looper = looper;
wrappedBuilder.setLooper(looper);
return this;
}
@ -716,8 +745,124 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setAnalyticsCollector(AnalyticsCollector analyticsCollector) {
Assertions.checkState(!buildCalled);
this.analyticsCollector = analyticsCollector;
wrappedBuilder.setAnalyticsCollector(analyticsCollector);
return this;
}
/**
* Sets an {@link PriorityTaskManager} that will be used by the player.
*
* <p>The priority {@link C#PRIORITY_PLAYBACK} will be set while the player is loading.
*
* @param priorityTaskManager A {@link PriorityTaskManager}, or null to not use one.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setPriorityTaskManager(@Nullable PriorityTaskManager priorityTaskManager) {
wrappedBuilder.setPriorityTaskManager(priorityTaskManager);
return this;
}
/**
* Sets {@link AudioAttributes} that will be used by the player and whether to handle audio
* focus.
*
* <p>If audio focus should be handled, the {@link AudioAttributes#usage} must be {@link
* C#USAGE_MEDIA} or {@link C#USAGE_GAME}. Other usages will throw an {@link
* IllegalArgumentException}.
*
* @param audioAttributes {@link AudioAttributes}.
* @param handleAudioFocus Whether the player should handle audio focus.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus) {
wrappedBuilder.setAudioAttributes(audioAttributes, handleAudioFocus);
return this;
}
/**
* Sets the {@link C.WakeMode} that will be used by the player.
*
* <p>Enabling this feature requires the {@link android.Manifest.permission#WAKE_LOCK}
* permission. It should be used together with a foreground {@link android.app.Service} for use
* cases where playback occurs and the screen is off (e.g. background audio playback). It is not
* useful when the screen will be kept on during playback (e.g. foreground video playback).
*
* <p>When enabled, the locks ({@link android.os.PowerManager.WakeLock} / {@link
* android.net.wifi.WifiManager.WifiLock}) will be held whenever the player is in the {@link
* #STATE_READY} or {@link #STATE_BUFFERING} states with {@code playWhenReady = true}. The locks
* held depend on the specified {@link C.WakeMode}.
*
* @param wakeMode A {@link C.WakeMode}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setWakeMode(@C.WakeMode int wakeMode) {
wrappedBuilder.setWakeMode(wakeMode);
return this;
}
/**
* Sets whether the player should pause automatically when audio is rerouted from a headset to
* device speakers. See the <a
* href="https://developer.android.com/guide/topics/media-apps/volume-and-earphones#becoming-noisy">
* audio becoming noisy</a> documentation for more information.
*
* @param handleAudioBecomingNoisy Whether the player should pause automatically when audio is
* rerouted from a headset to device speakers.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setHandleAudioBecomingNoisy(boolean handleAudioBecomingNoisy) {
wrappedBuilder.setHandleAudioBecomingNoisy(handleAudioBecomingNoisy);
return this;
}
/**
* Sets whether silences silences in the audio stream is enabled.
*
* @param skipSilenceEnabled Whether skipping silences is enabled.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setSkipSilenceEnabled(boolean skipSilenceEnabled) {
wrappedBuilder.setSkipSilenceEnabled(skipSilenceEnabled);
return this;
}
/**
* Sets the {@link C.VideoScalingMode} that will be used by the player.
*
* <p>The scaling mode only applies if a {@link MediaCodec}-based video {@link Renderer} is
* enabled and if the output surface is owned by a {@link SurfaceView}.
*
* @param videoScalingMode A {@link C.VideoScalingMode}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setVideoScalingMode(@C.VideoScalingMode int videoScalingMode) {
wrappedBuilder.setVideoScalingMode(videoScalingMode);
return this;
}
/**
* Sets a {@link C.VideoChangeFrameRateStrategy} that will be used by the player when provided
* with a video output {@link Surface}.
*
* <p>The strategy only applies if a {@link MediaCodec}-based video {@link Renderer} is enabled.
* Applications wishing to use {@link Surface#CHANGE_FRAME_RATE_ALWAYS} should set the mode to
* {@link C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_OFF} to disable calls to {@link
* Surface#setFrameRate} from ExoPlayer, and should then call {@link Surface#setFrameRate}
* directly from application code.
*
* @param videoChangeFrameRateStrategy A {@link C.VideoChangeFrameRateStrategy}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setVideoChangeFrameRateStrategy(
@C.VideoChangeFrameRateStrategy int videoChangeFrameRateStrategy) {
wrappedBuilder.setVideoChangeFrameRateStrategy(videoChangeFrameRateStrategy);
return this;
}
@ -733,8 +878,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setUseLazyPreparation(boolean useLazyPreparation) {
Assertions.checkState(!buildCalled);
this.useLazyPreparation = useLazyPreparation;
wrappedBuilder.setUseLazyPreparation(useLazyPreparation);
return this;
}
@ -746,8 +890,33 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setSeekParameters(SeekParameters seekParameters) {
Assertions.checkState(!buildCalled);
this.seekParameters = seekParameters;
wrappedBuilder.setSeekParameters(seekParameters);
return this;
}
/**
* Sets the {@link #seekBack()} increment.
*
* @param seekBackIncrementMs The seek back increment, in milliseconds.
* @return This builder.
* @throws IllegalArgumentException If {@code seekBackIncrementMs} is non-positive.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setSeekBackIncrementMs(@IntRange(from = 1) long seekBackIncrementMs) {
wrappedBuilder.setSeekBackIncrementMs(seekBackIncrementMs);
return this;
}
/**
* Sets the {@link #seekForward()} increment.
*
* @param seekForwardIncrementMs The seek forward increment, in milliseconds.
* @return This builder.
* @throws IllegalArgumentException If {@code seekForwardIncrementMs} is non-positive.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setSeekForwardIncrementMs(@IntRange(from = 1) long seekForwardIncrementMs) {
wrappedBuilder.setSeekForwardIncrementMs(seekForwardIncrementMs);
return this;
}
@ -763,8 +932,23 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setReleaseTimeoutMs(long releaseTimeoutMs) {
Assertions.checkState(!buildCalled);
this.releaseTimeoutMs = releaseTimeoutMs;
wrappedBuilder.setReleaseTimeoutMs(releaseTimeoutMs);
return this;
}
/**
* Sets a timeout for detaching a surface from the player.
*
* <p>If detaching a surface or replacing a surface takes more than {@code
* detachSurfaceTimeoutMs} to complete, the player will report an error via {@link
* Player.Listener#onPlayerError}.
*
* @param detachSurfaceTimeoutMs The timeout for detaching a surface, in milliseconds.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setDetachSurfaceTimeoutMs(long detachSurfaceTimeoutMs) {
wrappedBuilder.setDetachSurfaceTimeoutMs(detachSurfaceTimeoutMs);
return this;
}
@ -781,8 +965,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setPauseAtEndOfMediaItems(boolean pauseAtEndOfMediaItems) {
Assertions.checkState(!buildCalled);
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
wrappedBuilder.setPauseAtEndOfMediaItems(pauseAtEndOfMediaItems);
return this;
}
@ -795,8 +978,7 @@ public interface ExoPlayer extends Player {
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setLivePlaybackSpeedControl(LivePlaybackSpeedControl livePlaybackSpeedControl) {
Assertions.checkState(!buildCalled);
this.livePlaybackSpeedControl = livePlaybackSpeedControl;
wrappedBuilder.setLivePlaybackSpeedControl(livePlaybackSpeedControl);
return this;
}
@ -810,45 +992,28 @@ public interface ExoPlayer extends Player {
*/
@VisibleForTesting
public Builder setClock(Clock clock) {
Assertions.checkState(!buildCalled);
this.clock = clock;
wrappedBuilder.setClock(clock);
return this;
}
/**
* Builds an {@link ExoPlayer} instance.
* Builds a {@link SimpleExoPlayer} instance.
*
* @throws IllegalStateException If {@code build} has already been called.
* @throws IllegalStateException If this method has already been called.
*/
public ExoPlayer build() {
Assertions.checkState(!buildCalled);
buildCalled = true;
ExoPlayerImpl player =
new ExoPlayerImpl(
renderers,
trackSelector,
mediaSourceFactory,
loadControl,
bandwidthMeter,
analyticsCollector,
useLazyPreparation,
seekParameters,
C.DEFAULT_SEEK_BACK_INCREMENT_MS,
C.DEFAULT_SEEK_FORWARD_INCREMENT_MS,
livePlaybackSpeedControl,
releaseTimeoutMs,
pauseAtEndOfMediaItems,
clock,
looper,
/* wrappingPlayer= */ null,
/* additionalPermanentAvailableCommands= */ Commands.EMPTY);
public SimpleExoPlayer build() {
return wrappedBuilder.build();
}
}
if (setForegroundModeTimeoutMs > 0) {
player.experimentalSetForegroundModeTimeoutMs(setForegroundModeTimeoutMs);
}
return player;
}
}
/**
* The default timeout for calls to {@link #release} and {@link #setForegroundMode}, in
* milliseconds.
*/
long DEFAULT_RELEASE_TIMEOUT_MS = 500;
/** The default timeout for detaching a surface from the player, in milliseconds. */
long DEFAULT_DETACH_SURFACE_TIMEOUT_MS = 2_000;
/**
* Equivalent to {@link Player#getPlayerError()}, except the exception is guaranteed to be an

View File

@ -35,7 +35,6 @@ import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.media.AudioFormat;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Handler;
import android.os.Looper;
@ -91,7 +90,7 @@ import java.util.concurrent.TimeoutException;
/**
* An {@link ExoPlayer} implementation that uses default {@link Renderer} components. Instances can
* be obtained from {@link SimpleExoPlayer.Builder}.
* be obtained from {@link ExoPlayer.Builder}.
*/
public class SimpleExoPlayer extends BasePlayer
implements ExoPlayer,
@ -101,14 +100,9 @@ public class SimpleExoPlayer extends BasePlayer
ExoPlayer.MetadataComponent,
ExoPlayer.DeviceComponent {
/** The default timeout for detaching a surface from the player, in milliseconds. */
public static final long DEFAULT_DETACH_SURFACE_TIMEOUT_MS = 2_000;
/**
* A builder for {@link SimpleExoPlayer} instances.
*
* <p>See {@link #Builder(Context)} for the list of default values.
*/
/** @deprecated Use {@link ExoPlayer.Builder} instead. */
@Deprecated
@SuppressWarnings("deprecation")
public static final class Builder {
private final Context context;
@ -140,89 +134,29 @@ public class SimpleExoPlayer extends BasePlayer
private boolean pauseAtEndOfMediaItems;
private boolean buildCalled;
/**
* Creates a builder.
*
* <p>Use {@link #Builder(Context, RenderersFactory)}, {@link #Builder(Context,
* RenderersFactory)} or {@link #Builder(Context, RenderersFactory, ExtractorsFactory)} instead,
* if you intend to provide a custom {@link RenderersFactory} or a custom {@link
* ExtractorsFactory}. This is to ensure that ProGuard or R8 can remove ExoPlayer's {@link
* DefaultRenderersFactory} and {@link DefaultExtractorsFactory} from the APK.
*
* <p>The builder uses the following default values:
*
* <ul>
* <li>{@link RenderersFactory}: {@link DefaultRenderersFactory}
* <li>{@link TrackSelector}: {@link DefaultTrackSelector}
* <li>{@link MediaSourceFactory}: {@link DefaultMediaSourceFactory}
* <li>{@link LoadControl}: {@link DefaultLoadControl}
* <li>{@link BandwidthMeter}: {@link DefaultBandwidthMeter#getSingletonInstance(Context)}
* <li>{@link LivePlaybackSpeedControl}: {@link DefaultLivePlaybackSpeedControl}
* <li>{@link Looper}: The {@link Looper} associated with the current thread, or the {@link
* Looper} of the application's main thread if the current thread doesn't have a {@link
* Looper}
* <li>{@link AnalyticsCollector}: {@link AnalyticsCollector} with {@link Clock#DEFAULT}
* <li>{@link PriorityTaskManager}: {@code null} (not used)
* <li>{@link AudioAttributes}: {@link AudioAttributes#DEFAULT}, not handling audio focus
* <li>{@link C.WakeMode}: {@link C#WAKE_MODE_NONE}
* <li>{@code handleAudioBecomingNoisy}: {@code false}
* <li>{@code skipSilenceEnabled}: {@code false}
* <li>{@link C.VideoScalingMode}: {@link C#VIDEO_SCALING_MODE_DEFAULT}
* <li>{@link C.VideoChangeFrameRateStrategy}: {@link
* C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_ONLY_IF_SEAMLESS}
* <li>{@code useLazyPreparation}: {@code true}
* <li>{@link SeekParameters}: {@link SeekParameters#DEFAULT}
* <li>{@code seekBackIncrementMs}: {@link C#DEFAULT_SEEK_BACK_INCREMENT_MS}
* <li>{@code seekForwardIncrementMs}: {@link C#DEFAULT_SEEK_FORWARD_INCREMENT_MS}
* <li>{@code releaseTimeoutMs}: {@link ExoPlayer#DEFAULT_RELEASE_TIMEOUT_MS}
* <li>{@code detachSurfaceTimeoutMs}: {@link #DEFAULT_DETACH_SURFACE_TIMEOUT_MS}
* <li>{@code pauseAtEndOfMediaItems}: {@code false}
* <li>{@link Clock}: {@link Clock#DEFAULT}
* </ul>
*
* @param context A {@link Context}.
*/
/** @deprecated Use {@link ExoPlayer.Builder#Builder(Context)} instead. */
@Deprecated
public Builder(Context context) {
this(context, new DefaultRenderersFactory(context), new DefaultExtractorsFactory());
}
/**
* Creates a builder with a custom {@link RenderersFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
* player.
*/
/** @deprecated Use {@link ExoPlayer.Builder#Builder(Context, RenderersFactory)} instead. */
@Deprecated
public Builder(Context context, RenderersFactory renderersFactory) {
this(context, renderersFactory, new DefaultExtractorsFactory());
}
/**
* Creates a builder with a custom {@link ExtractorsFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
* its container.
*/
/** @deprecated Use {@link ExoPlayer.Builder#Builder(Context, ExtractorsFactory)} instead. */
@Deprecated
public Builder(Context context, ExtractorsFactory extractorsFactory) {
this(context, new DefaultRenderersFactory(context), extractorsFactory);
}
/**
* Creates a builder with a custom {@link RenderersFactory} and {@link ExtractorsFactory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
* player.
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
* its container.
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, RenderersFactory,
* ExtractorsFactory)} instead.
*/
@Deprecated
public Builder(
Context context, RenderersFactory renderersFactory, ExtractorsFactory extractorsFactory) {
this(
@ -236,20 +170,10 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Creates a builder with the specified custom components.
*
* <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 context A {@link Context}.
* @param renderersFactory A factory for creating {@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 analyticsCollector An {@link AnalyticsCollector}.
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, RenderersFactory, TrackSelector,
* MediaSourceFactory, LoadControl, BandwidthMeter, AnalyticsCollector)} instead.
*/
@Deprecated
public Builder(
Context context,
RenderersFactory renderersFactory,
@ -276,32 +200,23 @@ public class SimpleExoPlayer extends BasePlayer
seekForwardIncrementMs = C.DEFAULT_SEEK_FORWARD_INCREMENT_MS;
livePlaybackSpeedControl = new DefaultLivePlaybackSpeedControl.Builder().build();
clock = Clock.DEFAULT;
releaseTimeoutMs = ExoPlayer.DEFAULT_RELEASE_TIMEOUT_MS;
releaseTimeoutMs = DEFAULT_RELEASE_TIMEOUT_MS;
detachSurfaceTimeoutMs = DEFAULT_DETACH_SURFACE_TIMEOUT_MS;
}
/**
* Set a limit on the time a call to {@link #setForegroundMode} can spend. If a call to {@link
* #setForegroundMode} takes more than {@code timeoutMs} milliseconds to complete, the player
* will raise an error via {@link Player.Listener#onPlayerError}.
*
* <p>This method is experimental, and will be renamed or removed in a future release.
*
* @param timeoutMs The time limit in milliseconds.
* @deprecated Use {@link ExoPlayer.Builder#experimentalSetForegroundModeTimeoutMs(long)}
* instead.
*/
@Deprecated
public Builder experimentalSetForegroundModeTimeoutMs(long timeoutMs) {
Assertions.checkState(!buildCalled);
foregroundModeTimeoutMs = timeoutMs;
return this;
}
/**
* Sets the {@link TrackSelector} that will be used by the player.
*
* @param trackSelector A {@link TrackSelector}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setTrackSelector(TrackSelector)} instead. */
@Deprecated
public Builder setTrackSelector(TrackSelector trackSelector) {
Assertions.checkState(!buildCalled);
this.trackSelector = trackSelector;
@ -309,52 +224,33 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Sets the {@link MediaSourceFactory} that will be used by the player.
*
* @param mediaSourceFactory A {@link MediaSourceFactory}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
* @deprecated Use {@link ExoPlayer.Builder#setMediaSourceFactory(MediaSourceFactory)} instead.
*/
@Deprecated
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
Assertions.checkState(!buildCalled);
this.mediaSourceFactory = mediaSourceFactory;
return this;
}
/**
* Sets the {@link LoadControl} that will be used by the player.
*
* @param loadControl A {@link LoadControl}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setLoadControl(LoadControl)} instead. */
@Deprecated
public Builder setLoadControl(LoadControl loadControl) {
Assertions.checkState(!buildCalled);
this.loadControl = loadControl;
return this;
}
/**
* Sets the {@link BandwidthMeter} that will be used by the player.
*
* @param bandwidthMeter A {@link BandwidthMeter}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setBandwidthMeter(BandwidthMeter)} instead. */
@Deprecated
public Builder setBandwidthMeter(BandwidthMeter bandwidthMeter) {
Assertions.checkState(!buildCalled);
this.bandwidthMeter = bandwidthMeter;
return this;
}
/**
* Sets the {@link Looper} that must be used for all calls to the player and that is used to
* call listeners on.
*
* @param looper A {@link Looper}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setLooper(Looper)} instead. */
@Deprecated
public Builder setLooper(Looper looper) {
Assertions.checkState(!buildCalled);
this.looper = looper;
@ -362,12 +258,9 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Sets the {@link AnalyticsCollector} that will collect and forward all player events.
*
* @param analyticsCollector An {@link AnalyticsCollector}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
* @deprecated Use {@link ExoPlayer.Builder#setAnalyticsCollector(AnalyticsCollector)} instead.
*/
@Deprecated
public Builder setAnalyticsCollector(AnalyticsCollector analyticsCollector) {
Assertions.checkState(!buildCalled);
this.analyticsCollector = analyticsCollector;
@ -375,14 +268,10 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Sets an {@link PriorityTaskManager} that will be used by the player.
*
* <p>The priority {@link C#PRIORITY_PLAYBACK} will be set while the player is loading.
*
* @param priorityTaskManager A {@link PriorityTaskManager}, or null to not use one.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
* @deprecated Use {@link ExoPlayer.Builder#setPriorityTaskManager(PriorityTaskManager)}
* instead.
*/
@Deprecated
public Builder setPriorityTaskManager(@Nullable PriorityTaskManager priorityTaskManager) {
Assertions.checkState(!buildCalled);
this.priorityTaskManager = priorityTaskManager;
@ -390,18 +279,10 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Sets {@link AudioAttributes} that will be used by the player and whether to handle audio
* focus.
*
* <p>If audio focus should be handled, the {@link AudioAttributes#usage} must be {@link
* C#USAGE_MEDIA} or {@link C#USAGE_GAME}. Other usages will throw an {@link
* IllegalArgumentException}.
*
* @param audioAttributes {@link AudioAttributes}.
* @param handleAudioFocus Whether the player should handle audio focus.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
* @deprecated Use {@link ExoPlayer.Builder#setAudioAttributes(AudioAttributes, boolean)}
* instead.
*/
@Deprecated
public Builder setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus) {
Assertions.checkState(!buildCalled);
this.audioAttributes = audioAttributes;
@ -409,89 +290,40 @@ public class SimpleExoPlayer extends BasePlayer
return this;
}
/**
* Sets the {@link C.WakeMode} that will be used by the player.
*
* <p>Enabling this feature requires the {@link android.Manifest.permission#WAKE_LOCK}
* permission. It should be used together with a foreground {@link android.app.Service} for use
* cases where playback occurs and the screen is off (e.g. background audio playback). It is not
* useful when the screen will be kept on during playback (e.g. foreground video playback).
*
* <p>When enabled, the locks ({@link android.os.PowerManager.WakeLock} / {@link
* android.net.wifi.WifiManager.WifiLock}) will be held whenever the player is in the {@link
* #STATE_READY} or {@link #STATE_BUFFERING} states with {@code playWhenReady = true}. The locks
* held depend on the specified {@link C.WakeMode}.
*
* @param wakeMode A {@link C.WakeMode}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setWakeMode(int)} instead. */
@Deprecated
public Builder setWakeMode(@C.WakeMode int wakeMode) {
Assertions.checkState(!buildCalled);
this.wakeMode = wakeMode;
return this;
}
/**
* Sets whether the player should pause automatically when audio is rerouted from a headset to
* device speakers. See the <a
* href="https://developer.android.com/guide/topics/media-apps/volume-and-earphones#becoming-noisy">audio
* becoming noisy</a> documentation for more information.
*
* @param handleAudioBecomingNoisy Whether the player should pause automatically when audio is
* rerouted from a headset to device speakers.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setHandleAudioBecomingNoisy(boolean)} instead. */
@Deprecated
public Builder setHandleAudioBecomingNoisy(boolean handleAudioBecomingNoisy) {
Assertions.checkState(!buildCalled);
this.handleAudioBecomingNoisy = handleAudioBecomingNoisy;
return this;
}
/**
* Sets whether silences silences in the audio stream is enabled.
*
* @param skipSilenceEnabled Whether skipping silences is enabled.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setSkipSilenceEnabled(boolean)} instead. */
@Deprecated
public Builder setSkipSilenceEnabled(boolean skipSilenceEnabled) {
Assertions.checkState(!buildCalled);
this.skipSilenceEnabled = skipSilenceEnabled;
return this;
}
/**
* Sets the {@link C.VideoScalingMode} that will be used by the player.
*
* <p>The scaling mode only applies if a {@link MediaCodec}-based video {@link Renderer} is
* enabled and if the output surface is owned by a {@link SurfaceView}.
*
* @param videoScalingMode A {@link C.VideoScalingMode}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setVideoScalingMode(int)} instead. */
@Deprecated
public Builder setVideoScalingMode(@C.VideoScalingMode int videoScalingMode) {
Assertions.checkState(!buildCalled);
this.videoScalingMode = videoScalingMode;
return this;
}
/**
* Sets a {@link C.VideoChangeFrameRateStrategy} that will be used by the player when provided
* with a video output {@link Surface}.
*
* <p>The strategy only applies if a {@link MediaCodec}-based video {@link Renderer} is enabled.
* Applications wishing to use {@link Surface#CHANGE_FRAME_RATE_ALWAYS} should set the mode to
* {@link C#VIDEO_CHANGE_FRAME_RATE_STRATEGY_OFF} to disable calls to {@link
* Surface#setFrameRate} from ExoPlayer, and should then call {@link Surface#setFrameRate}
* directly from application code.
*
* @param videoChangeFrameRateStrategy A {@link C.VideoChangeFrameRateStrategy}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setVideoChangeFrameRateStrategy(int)} instead. */
@Deprecated
public Builder setVideoChangeFrameRateStrategy(
@C.VideoChangeFrameRateStrategy int videoChangeFrameRateStrategy) {
Assertions.checkState(!buildCalled);
@ -499,44 +331,24 @@ public class SimpleExoPlayer extends BasePlayer
return this;
}
/**
* Sets whether media sources should be initialized lazily.
*
* <p>If false, all initial preparation steps (e.g., manifest loads) happen immediately. If
* true, these initial preparations are triggered only when the player starts buffering the
* media.
*
* @param useLazyPreparation Whether to use lazy preparation.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setUseLazyPreparation(boolean)} instead. */
@Deprecated
public Builder setUseLazyPreparation(boolean useLazyPreparation) {
Assertions.checkState(!buildCalled);
this.useLazyPreparation = useLazyPreparation;
return this;
}
/**
* 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.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setSeekParameters(SeekParameters)} instead. */
@Deprecated
public Builder setSeekParameters(SeekParameters seekParameters) {
Assertions.checkState(!buildCalled);
this.seekParameters = seekParameters;
return this;
}
/**
* Sets the {@link #seekBack()} increment.
*
* @param seekBackIncrementMs The seek back increment, in milliseconds.
* @return This builder.
* @throws IllegalArgumentException If {@code seekBackIncrementMs} is non-positive.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setSeekBackIncrementMs(long)} instead. */
@Deprecated
public Builder setSeekBackIncrementMs(@IntRange(from = 1) long seekBackIncrementMs) {
checkArgument(seekBackIncrementMs > 0);
Assertions.checkState(!buildCalled);
@ -544,14 +356,8 @@ public class SimpleExoPlayer extends BasePlayer
return this;
}
/**
* Sets the {@link #seekForward()} increment.
*
* @param seekForwardIncrementMs The seek forward increment, in milliseconds.
* @return This builder.
* @throws IllegalArgumentException If {@code seekForwardIncrementMs} is non-positive.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setSeekForwardIncrementMs(long)} instead. */
@Deprecated
public Builder setSeekForwardIncrementMs(@IntRange(from = 1) long seekForwardIncrementMs) {
checkArgument(seekForwardIncrementMs > 0);
Assertions.checkState(!buildCalled);
@ -559,52 +365,24 @@ public class SimpleExoPlayer extends BasePlayer
return this;
}
/**
* Sets a timeout for calls to {@link #release} and {@link #setForegroundMode}.
*
* <p>If a call to {@link #release} or {@link #setForegroundMode} takes more than {@code
* timeoutMs} to complete, the player will report an error via {@link
* Player.Listener#onPlayerError}.
*
* @param releaseTimeoutMs The release timeout, in milliseconds.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setReleaseTimeoutMs(long)} instead. */
@Deprecated
public Builder setReleaseTimeoutMs(long releaseTimeoutMs) {
Assertions.checkState(!buildCalled);
this.releaseTimeoutMs = releaseTimeoutMs;
return this;
}
/**
* Sets a timeout for detaching a surface from the player.
*
* <p>If detaching a surface or replacing a surface takes more than {@code
* detachSurfaceTimeoutMs} to complete, the player will report an error via {@link
* Player.Listener#onPlayerError}.
*
* @param detachSurfaceTimeoutMs The timeout for detaching a surface, in milliseconds.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setDetachSurfaceTimeoutMs(long)} instead. */
@Deprecated
public Builder setDetachSurfaceTimeoutMs(long detachSurfaceTimeoutMs) {
Assertions.checkState(!buildCalled);
this.detachSurfaceTimeoutMs = detachSurfaceTimeoutMs;
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.Listener#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.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setPauseAtEndOfMediaItems(boolean)} instead. */
@Deprecated
public Builder setPauseAtEndOfMediaItems(boolean pauseAtEndOfMediaItems) {
Assertions.checkState(!buildCalled);
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
@ -612,27 +390,18 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* Sets the {@link LivePlaybackSpeedControl} that will control the playback speed when playing
* live streams, in order to maintain a steady target offset from the live stream edge.
*
* @param livePlaybackSpeedControl The {@link LivePlaybackSpeedControl}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
* @deprecated Use {@link
* ExoPlayer.Builder#setLivePlaybackSpeedControl(LivePlaybackSpeedControl)} instead.
*/
@Deprecated
public Builder setLivePlaybackSpeedControl(LivePlaybackSpeedControl livePlaybackSpeedControl) {
Assertions.checkState(!buildCalled);
this.livePlaybackSpeedControl = livePlaybackSpeedControl;
return this;
}
/**
* Sets the {@link Clock} that will be used by the player. Should only be set for testing
* purposes.
*
* @param clock A {@link Clock}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#setClock(Clock)} instead. */
@Deprecated
@VisibleForTesting
public Builder setClock(Clock clock) {
Assertions.checkState(!buildCalled);
@ -640,11 +409,8 @@ public class SimpleExoPlayer extends BasePlayer
return this;
}
/**
* Builds a {@link SimpleExoPlayer} instance.
*
* @throws IllegalStateException If this method has already been called.
*/
/** @deprecated Use {@link ExoPlayer.Builder#build()} instead. */
@Deprecated
public SimpleExoPlayer build() {
Assertions.checkState(!buildCalled);
buildCalled = true;
@ -706,6 +472,7 @@ public class SimpleExoPlayer extends BasePlayer
/** @deprecated Use the {@link Builder} and pass it to {@link #SimpleExoPlayer(Builder)}. */
@Deprecated
@SuppressWarnings("deprecation")
protected SimpleExoPlayer(
Context context,
RenderersFactory renderersFactory,
@ -730,6 +497,7 @@ public class SimpleExoPlayer extends BasePlayer
}
/** @param builder The {@link Builder} to obtain all construction parameters. */
@SuppressWarnings("deprecation")
protected SimpleExoPlayer(Builder builder) {
constructorFinished = new ConditionVariable();
try {