summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java')
-rw-r--r--mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java
new file mode 100644
index 0000000000..89059dc2ea
--- /dev/null
+++ b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/Player.java
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mozilla.thirdparty.com.google.android.exoplayer2;
+
+import android.os.Looper;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.C.VideoScalingMode;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.audio.AudioAttributes;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.audio.AudioListener;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.audio.AuxEffectInfo;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.metadata.MetadataOutput;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.source.TrackGroupArray;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.text.TextOutput;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.trackselection.TrackSelectionArray;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.util.Util;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.video.VideoDecoderOutputBufferRenderer;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.video.VideoFrameMetadataListener;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.video.VideoListener;
+import org.mozilla.thirdparty.com.google.android.exoplayer2.video.spherical.CameraMotionListener;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A media player interface defining traditional high-level functionality, such as the ability to
+ * play, pause, seek and query properties of the currently playing media.
+ * <p>
+ * Some important properties of media players that implement this interface are:
+ * <ul>
+ * <li>They can provide a {@link Timeline} representing the structure of the media being played,
+ * which can be obtained by calling {@link #getCurrentTimeline()}.</li>
+ * <li>They can provide a {@link TrackGroupArray} defining the currently available tracks,
+ * which can be obtained by calling {@link #getCurrentTrackGroups()}.</li>
+ * <li>They contain a number of renderers, each of which is able to render tracks of a single
+ * type (e.g. audio, video or text). The number of renderers and their respective track types
+ * can be obtained by calling {@link #getRendererCount()} and {@link #getRendererType(int)}.
+ * </li>
+ * <li>They can provide a {@link TrackSelectionArray} defining which of the currently available
+ * tracks are selected to be rendered by each renderer. This can be obtained by calling
+ * {@link #getCurrentTrackSelections()}}.</li>
+ * </ul>
+ */
+public interface Player {
+
+ /** The audio component of a {@link Player}. */
+ interface AudioComponent {
+
+ /**
+ * Adds a listener to receive audio events.
+ *
+ * @param listener The listener to register.
+ */
+ void addAudioListener(AudioListener listener);
+
+ /**
+ * Removes a listener of audio events.
+ *
+ * @param listener The listener to unregister.
+ */
+ void removeAudioListener(AudioListener listener);
+
+ /**
+ * Sets the attributes for audio playback, used by the underlying audio track. If not set, the
+ * default audio attributes will be used. They are suitable for general media playback.
+ *
+ * <p>Setting the audio attributes during playback may introduce a short gap in audio output as
+ * the audio track is recreated. A new audio session id will also be generated.
+ *
+ * <p>If tunneling is enabled by the track selector, the specified audio attributes will be
+ * ignored, but they will take effect if audio is later played without tunneling.
+ *
+ * <p>If the device is running a build before platform API version 21, audio attributes cannot
+ * be set directly on the underlying audio track. In this case, the usage will be mapped onto an
+ * equivalent stream type using {@link Util#getStreamTypeForAudioUsage(int)}.
+ *
+ * @param audioAttributes The attributes to use for audio playback.
+ * @deprecated Use {@link AudioComponent#setAudioAttributes(AudioAttributes, boolean)}.
+ */
+ @Deprecated
+ void setAudioAttributes(AudioAttributes audioAttributes);
+
+ /**
+ * Sets the attributes for audio playback, used by the underlying audio track. If not set, the
+ * default audio attributes will be used. They are suitable for general media playback.
+ *
+ * <p>Setting the audio attributes during playback may introduce a short gap in audio output as
+ * the audio track is recreated. A new audio session id will also be generated.
+ *
+ * <p>If tunneling is enabled by the track selector, the specified audio attributes will be
+ * ignored, but they will take effect if audio is later played without tunneling.
+ *
+ * <p>If the device is running a build before platform API version 21, audio attributes cannot
+ * be set directly on the underlying audio track. In this case, the usage will be mapped onto an
+ * equivalent stream type using {@link Util#getStreamTypeForAudioUsage(int)}.
+ *
+ * <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 The attributes to use for audio playback.
+ * @param handleAudioFocus True if the player should handle audio focus, false otherwise.
+ */
+ void setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus);
+
+ /** Returns the attributes for audio playback. */
+ AudioAttributes getAudioAttributes();
+
+ /** Returns the audio session identifier, or {@link C#AUDIO_SESSION_ID_UNSET} if not set. */
+ int getAudioSessionId();
+
+ /** Sets information on an auxiliary audio effect to attach to the underlying audio track. */
+ void setAuxEffectInfo(AuxEffectInfo auxEffectInfo);
+
+ /** Detaches any previously attached auxiliary audio effect from the underlying audio track. */
+ void clearAuxEffectInfo();
+
+ /**
+ * Sets the audio volume, with 0 being silence and 1 being unity gain.
+ *
+ * @param audioVolume The audio volume.
+ */
+ void setVolume(float audioVolume);
+
+ /** Returns the audio volume, with 0 being silence and 1 being unity gain. */
+ float getVolume();
+ }
+
+ /** The video component of a {@link Player}. */
+ interface VideoComponent {
+
+ /**
+ * Sets the {@link VideoScalingMode}.
+ *
+ * @param videoScalingMode The {@link VideoScalingMode}.
+ */
+ void setVideoScalingMode(@VideoScalingMode int videoScalingMode);
+
+ /** Returns the {@link VideoScalingMode}. */
+ @VideoScalingMode
+ int getVideoScalingMode();
+
+ /**
+ * Adds a listener to receive video events.
+ *
+ * @param listener The listener to register.
+ */
+ void addVideoListener(VideoListener listener);
+
+ /**
+ * Removes a listener of video events.
+ *
+ * @param listener The listener to unregister.
+ */
+ void removeVideoListener(VideoListener listener);
+
+ /**
+ * Sets a listener to receive video frame metadata events.
+ *
+ * <p>This method is intended to be called by the same component that sets the {@link Surface}
+ * onto which video will be rendered. If using ExoPlayer's standard UI components, this method
+ * should not be called directly from application code.
+ *
+ * @param listener The listener.
+ */
+ void setVideoFrameMetadataListener(VideoFrameMetadataListener listener);
+
+ /**
+ * Clears the listener which receives video frame metadata events if it matches the one passed.
+ * Else does nothing.
+ *
+ * @param listener The listener to clear.
+ */
+ void clearVideoFrameMetadataListener(VideoFrameMetadataListener listener);
+
+ /**
+ * Sets a listener of camera motion events.
+ *
+ * @param listener The listener.
+ */
+ void setCameraMotionListener(CameraMotionListener listener);
+
+ /**
+ * Clears the listener which receives camera motion events if it matches the one passed. Else
+ * does nothing.
+ *
+ * @param listener The listener to clear.
+ */
+ void clearCameraMotionListener(CameraMotionListener listener);
+
+ /**
+ * Clears any {@link Surface}, {@link SurfaceHolder}, {@link SurfaceView} or {@link TextureView}
+ * currently set on the player.
+ */
+ void clearVideoSurface();
+
+ /**
+ * Clears the {@link Surface} onto which video is being rendered if it matches the one passed.
+ * Else does nothing.
+ *
+ * @param surface The surface to clear.
+ */
+ void clearVideoSurface(@Nullable Surface surface);
+
+ /**
+ * Sets the {@link Surface} onto which video will be rendered. The caller is responsible for
+ * tracking the lifecycle of the surface, and must clear the surface by calling {@code
+ * setVideoSurface(null)} if the surface is destroyed.
+ *
+ * <p>If the surface is held by a {@link SurfaceView}, {@link TextureView} or {@link
+ * SurfaceHolder} then it's recommended to use {@link #setVideoSurfaceView(SurfaceView)}, {@link
+ * #setVideoTextureView(TextureView)} or {@link #setVideoSurfaceHolder(SurfaceHolder)} rather
+ * than this method, since passing the holder allows the player to track the lifecycle of the
+ * surface automatically.
+ *
+ * @param surface The {@link Surface}.
+ */
+ void setVideoSurface(@Nullable Surface surface);
+
+ /**
+ * Sets the {@link SurfaceHolder} that holds the {@link Surface} onto which video will be
+ * rendered. The player will track the lifecycle of the surface automatically.
+ *
+ * @param surfaceHolder The surface holder.
+ */
+ void setVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder);
+
+ /**
+ * Clears the {@link SurfaceHolder} that holds the {@link Surface} onto which video is being
+ * rendered if it matches the one passed. Else does nothing.
+ *
+ * @param surfaceHolder The surface holder to clear.
+ */
+ void clearVideoSurfaceHolder(@Nullable SurfaceHolder surfaceHolder);
+
+ /**
+ * Sets the {@link SurfaceView} onto which video will be rendered. The player will track the
+ * lifecycle of the surface automatically.
+ *
+ * @param surfaceView The surface view.
+ */
+ void setVideoSurfaceView(@Nullable SurfaceView surfaceView);
+
+ /**
+ * Clears the {@link SurfaceView} onto which video is being rendered if it matches the one
+ * passed. Else does nothing.
+ *
+ * @param surfaceView The texture view to clear.
+ */
+ void clearVideoSurfaceView(@Nullable SurfaceView surfaceView);
+
+ /**
+ * Sets the {@link TextureView} onto which video will be rendered. The player will track the
+ * lifecycle of the surface automatically.
+ *
+ * @param textureView The texture view.
+ */
+ void setVideoTextureView(@Nullable TextureView textureView);
+
+ /**
+ * Clears the {@link TextureView} onto which video is being rendered if it matches the one
+ * passed. Else does nothing.
+ *
+ * @param textureView The texture view to clear.
+ */
+ void clearVideoTextureView(@Nullable TextureView textureView);
+
+ /**
+ * Sets the video decoder output buffer renderer. This is intended for use only with extension
+ * renderers that accept {@link C#MSG_SET_VIDEO_DECODER_OUTPUT_BUFFER_RENDERER}. For most use
+ * cases, an output surface or view should be passed via {@link #setVideoSurface(Surface)} or
+ * {@link #setVideoSurfaceView(SurfaceView)} instead.
+ *
+ * @param videoDecoderOutputBufferRenderer The video decoder output buffer renderer, or {@code
+ * null} to clear the output buffer renderer.
+ */
+ void setVideoDecoderOutputBufferRenderer(
+ @Nullable VideoDecoderOutputBufferRenderer videoDecoderOutputBufferRenderer);
+
+ /** Clears the video decoder output buffer renderer. */
+ void clearVideoDecoderOutputBufferRenderer();
+
+ /**
+ * Clears the video decoder output buffer renderer if it matches the one passed. Else does
+ * nothing.
+ *
+ * @param videoDecoderOutputBufferRenderer The video decoder output buffer renderer to clear.
+ */
+ void clearVideoDecoderOutputBufferRenderer(
+ @Nullable VideoDecoderOutputBufferRenderer videoDecoderOutputBufferRenderer);
+ }
+
+ /** The text component of a {@link Player}. */
+ interface TextComponent {
+
+ /**
+ * Registers an output to receive text events.
+ *
+ * @param listener The output to register.
+ */
+ void addTextOutput(TextOutput listener);
+
+ /**
+ * Removes a text output.
+ *
+ * @param listener The output to remove.
+ */
+ void removeTextOutput(TextOutput listener);
+ }
+
+ /** The metadata component of a {@link Player}. */
+ interface MetadataComponent {
+
+ /**
+ * Adds a {@link MetadataOutput} to receive metadata.
+ *
+ * @param output The output to register.
+ */
+ void addMetadataOutput(MetadataOutput output);
+
+ /**
+ * Removes a {@link MetadataOutput}.
+ *
+ * @param output The output to remove.
+ */
+ void removeMetadataOutput(MetadataOutput output);
+ }
+
+ /**
+ * Listener of changes in player state. All methods have no-op default implementations to allow
+ * selective overrides.
+ */
+ interface EventListener {
+
+ /**
+ * Called when the timeline has been refreshed.
+ *
+ * <p>Note that if the timeline has changed then a position discontinuity may also have
+ * occurred. For example, the current period index may have changed as a result of periods being
+ * added or removed from the timeline. This will <em>not</em> be reported via a separate call to
+ * {@link #onPositionDiscontinuity(int)}.
+ *
+ * @param timeline The latest timeline. Never null, but may be empty.
+ * @param reason The {@link TimelineChangeReason} responsible for this timeline change.
+ */
+ @SuppressWarnings("deprecation")
+ default void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
+ Object manifest = null;
+ if (timeline.getWindowCount() == 1) {
+ // Legacy behavior was to report the manifest for single window timelines only.
+ Timeline.Window window = new Timeline.Window();
+ manifest = timeline.getWindow(0, window).manifest;
+ }
+ // Call deprecated version.
+ onTimelineChanged(timeline, manifest, reason);
+ }
+
+ /**
+ * Called when the timeline and/or manifest has been refreshed.
+ *
+ * <p>Note that if the timeline has changed then a position discontinuity may also have
+ * occurred. For example, the current period index may have changed as a result of periods being
+ * added or removed from the timeline. This will <em>not</em> be reported via a separate call to
+ * {@link #onPositionDiscontinuity(int)}.
+ *
+ * @param timeline The latest timeline. Never null, but may be empty.
+ * @param manifest The latest manifest. May be null.
+ * @param reason The {@link TimelineChangeReason} responsible for this timeline change.
+ * @deprecated Use {@link #onTimelineChanged(Timeline, int)} instead. The manifest can be
+ * accessed by using {@link #getCurrentManifest()} or {@code timeline.getWindow(windowIndex,
+ * window).manifest} for a given window index.
+ */
+ @Deprecated
+ default void onTimelineChanged(
+ Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {}
+
+ /**
+ * Called when the available or selected tracks change.
+ *
+ * @param trackGroups The available tracks. Never null, but may be of length zero.
+ * @param trackSelections The track selections for each renderer. Never null and always of
+ * length {@link #getRendererCount()}, but may contain null elements.
+ */
+ default void onTracksChanged(
+ TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
+
+ /**
+ * Called when the player starts or stops loading the source.
+ *
+ * @param isLoading Whether the source is currently being loaded.
+ */
+ default void onLoadingChanged(boolean isLoading) {}
+
+ /**
+ * Called when the value returned from either {@link #getPlayWhenReady()} or {@link
+ * #getPlaybackState()} changes.
+ *
+ * @param playWhenReady Whether playback will proceed when ready.
+ * @param playbackState The new {@link State playback state}.
+ */
+ default void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {}
+
+ /**
+ * Called when the value returned from {@link #getPlaybackSuppressionReason()} changes.
+ *
+ * @param playbackSuppressionReason The current {@link PlaybackSuppressionReason}.
+ */
+ default void onPlaybackSuppressionReasonChanged(
+ @PlaybackSuppressionReason int playbackSuppressionReason) {}
+
+ /**
+ * Called when the value of {@link #isPlaying()} changes.
+ *
+ * @param isPlaying Whether the player is playing.
+ */
+ default void onIsPlayingChanged(boolean isPlaying) {}
+
+ /**
+ * Called when the value of {@link #getRepeatMode()} changes.
+ *
+ * @param repeatMode The {@link RepeatMode} used for playback.
+ */
+ default void onRepeatModeChanged(@RepeatMode int repeatMode) {}
+
+ /**
+ * Called when the value of {@link #getShuffleModeEnabled()} changes.
+ *
+ * @param shuffleModeEnabled Whether shuffling of windows is enabled.
+ */
+ default void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {}
+
+ /**
+ * Called when an error occurs. The playback state will transition to {@link #STATE_IDLE}
+ * immediately after this method is called. The player instance can still be used, and {@link
+ * #release()} must still be called on the player should it no longer be required.
+ *
+ * @param error The error.
+ */
+ default void onPlayerError(ExoPlaybackException error) {}
+
+ /**
+ * Called when a position discontinuity occurs without a change to the timeline. A position
+ * discontinuity occurs when the current window or period index changes (as a result of playback
+ * transitioning from one period in the timeline to the next), or when the playback position
+ * jumps within the period currently being played (as a result of a seek being performed, or
+ * when the source introduces a discontinuity internally).
+ *
+ * <p>When a position discontinuity occurs as a result of a change to the timeline this method
+ * is <em>not</em> called. {@link #onTimelineChanged(Timeline, int)} is called in this case.
+ *
+ * @param reason The {@link DiscontinuityReason} responsible for the discontinuity.
+ */
+ default void onPositionDiscontinuity(@DiscontinuityReason int reason) {}
+
+ /**
+ * Called when the current playback parameters change. The playback parameters may change due to
+ * a call to {@link #setPlaybackParameters(PlaybackParameters)}, or the player itself may change
+ * them (for example, if audio playback switches to passthrough mode, where speed adjustment is
+ * no longer possible).
+ *
+ * @param playbackParameters The playback parameters.
+ */
+ default void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {}
+
+ /**
+ * Called when all pending seek requests have been processed by the player. This is guaranteed
+ * to happen after any necessary changes to the player state were reported to {@link
+ * #onPlayerStateChanged(boolean, int)}.
+ */
+ default void onSeekProcessed() {}
+ }
+
+ /**
+ * @deprecated Use {@link EventListener} interface directly for selective overrides as all methods
+ * are implemented as no-op default methods.
+ */
+ @Deprecated
+ abstract class DefaultEventListener implements EventListener {
+
+ @Override
+ public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
+ Object manifest = null;
+ if (timeline.getWindowCount() == 1) {
+ // Legacy behavior was to report the manifest for single window timelines only.
+ Timeline.Window window = new Timeline.Window();
+ manifest = timeline.getWindow(0, window).manifest;
+ }
+ // Call deprecated version.
+ onTimelineChanged(timeline, manifest, reason);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void onTimelineChanged(
+ Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) {
+ // Call deprecated version. Otherwise, do nothing.
+ onTimelineChanged(timeline, manifest);
+ }
+
+ /** @deprecated Use {@link EventListener#onTimelineChanged(Timeline, int)} instead. */
+ @Deprecated
+ public void onTimelineChanged(Timeline timeline, @Nullable Object manifest) {
+ // Do nothing.
+ }
+ }
+
+ /**
+ * Playback state. One of {@link #STATE_IDLE}, {@link #STATE_BUFFERING}, {@link #STATE_READY} or
+ * {@link #STATE_ENDED}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATE_IDLE, STATE_BUFFERING, STATE_READY, STATE_ENDED})
+ @interface State {}
+ /**
+ * The player does not have any media to play.
+ */
+ int STATE_IDLE = 1;
+ /**
+ * The player is not able to immediately play from its current position. This state typically
+ * occurs when more data needs to be loaded.
+ */
+ int STATE_BUFFERING = 2;
+ /**
+ * The player is able to immediately play from its current position. The player will be playing if
+ * {@link #getPlayWhenReady()} is true, and paused otherwise.
+ */
+ int STATE_READY = 3;
+ /**
+ * The player has finished playing the media.
+ */
+ int STATE_ENDED = 4;
+
+ /**
+ * Reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code true}. One
+ * of {@link #PLAYBACK_SUPPRESSION_REASON_NONE} or {@link
+ * #PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ PLAYBACK_SUPPRESSION_REASON_NONE,
+ PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS
+ })
+ @interface PlaybackSuppressionReason {}
+ /** Playback is not suppressed. */
+ int PLAYBACK_SUPPRESSION_REASON_NONE = 0;
+ /** Playback is suppressed due to transient audio focus loss. */
+ int PLAYBACK_SUPPRESSION_REASON_TRANSIENT_AUDIO_FOCUS_LOSS = 1;
+
+ /**
+ * Repeat modes for playback. One of {@link #REPEAT_MODE_OFF}, {@link #REPEAT_MODE_ONE} or {@link
+ * #REPEAT_MODE_ALL}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({REPEAT_MODE_OFF, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
+ @interface RepeatMode {}
+ /**
+ * Normal playback without repetition.
+ */
+ int REPEAT_MODE_OFF = 0;
+ /**
+ * "Repeat One" mode to repeat the currently playing window infinitely.
+ */
+ int REPEAT_MODE_ONE = 1;
+ /**
+ * "Repeat All" mode to repeat the entire timeline infinitely.
+ */
+ int REPEAT_MODE_ALL = 2;
+
+ /**
+ * Reasons for position discontinuities. One of {@link #DISCONTINUITY_REASON_PERIOD_TRANSITION},
+ * {@link #DISCONTINUITY_REASON_SEEK}, {@link #DISCONTINUITY_REASON_SEEK_ADJUSTMENT}, {@link
+ * #DISCONTINUITY_REASON_AD_INSERTION} or {@link #DISCONTINUITY_REASON_INTERNAL}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ DISCONTINUITY_REASON_PERIOD_TRANSITION,
+ DISCONTINUITY_REASON_SEEK,
+ DISCONTINUITY_REASON_SEEK_ADJUSTMENT,
+ DISCONTINUITY_REASON_AD_INSERTION,
+ DISCONTINUITY_REASON_INTERNAL
+ })
+ @interface DiscontinuityReason {}
+ /**
+ * Automatic playback transition from one period in the timeline to the next. The period index may
+ * be the same as it was before the discontinuity in case the current period is repeated.
+ */
+ int DISCONTINUITY_REASON_PERIOD_TRANSITION = 0;
+ /** Seek within the current period or to another period. */
+ int DISCONTINUITY_REASON_SEEK = 1;
+ /**
+ * Seek adjustment due to being unable to seek to the requested position or because the seek was
+ * permitted to be inexact.
+ */
+ int DISCONTINUITY_REASON_SEEK_ADJUSTMENT = 2;
+ /** Discontinuity to or from an ad within one period in the timeline. */
+ int DISCONTINUITY_REASON_AD_INSERTION = 3;
+ /** Discontinuity introduced internally by the source. */
+ int DISCONTINUITY_REASON_INTERNAL = 4;
+
+ /**
+ * Reasons for timeline changes. One of {@link #TIMELINE_CHANGE_REASON_PREPARED}, {@link
+ * #TIMELINE_CHANGE_REASON_RESET} or {@link #TIMELINE_CHANGE_REASON_DYNAMIC}.
+ */
+ @Documented
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TIMELINE_CHANGE_REASON_PREPARED,
+ TIMELINE_CHANGE_REASON_RESET,
+ TIMELINE_CHANGE_REASON_DYNAMIC
+ })
+ @interface TimelineChangeReason {}
+ /** Timeline and manifest changed as a result of a player initialization with new media. */
+ int TIMELINE_CHANGE_REASON_PREPARED = 0;
+ /** Timeline and manifest changed as a result of a player reset. */
+ int TIMELINE_CHANGE_REASON_RESET = 1;
+ /**
+ * Timeline or manifest changed as a result of an dynamic update introduced by the played media.
+ */
+ int TIMELINE_CHANGE_REASON_DYNAMIC = 2;
+
+ /** Returns the component of this player for audio output, or null if audio is not supported. */
+ @Nullable
+ AudioComponent getAudioComponent();
+
+ /** Returns the component of this player for video output, or null if video is not supported. */
+ @Nullable
+ VideoComponent getVideoComponent();
+
+ /** Returns the component of this player for text output, or null if text is not supported. */
+ @Nullable
+ TextComponent getTextComponent();
+
+ /**
+ * Returns the component of this player for metadata output, or null if metadata is not supported.
+ */
+ @Nullable
+ MetadataComponent getMetadataComponent();
+
+ /**
+ * Returns the {@link Looper} associated with the application thread that's used to access the
+ * player and on which player events are received.
+ */
+ Looper getApplicationLooper();
+
+ /**
+ * Register a listener to receive events from the player. The listener's methods will be called on
+ * the thread that was used to construct the player. However, if the thread used to construct the
+ * player does not have a {@link Looper}, then the listener will be called on the main thread.
+ *
+ * @param listener The listener to register.
+ */
+ void addListener(EventListener listener);
+
+ /**
+ * Unregister a listener. The listener will no longer receive events from the player.
+ *
+ * @param listener The listener to unregister.
+ */
+ void removeListener(EventListener listener);
+
+ /**
+ * Returns the current {@link State playback state} of the player.
+ *
+ * @return The current {@link State playback state}.
+ */
+ @State
+ int getPlaybackState();
+
+ /**
+ * Returns the reason why playback is suppressed even though {@link #getPlayWhenReady()} is {@code
+ * true}, or {@link #PLAYBACK_SUPPRESSION_REASON_NONE} if playback is not suppressed.
+ *
+ * @return The current {@link PlaybackSuppressionReason playback suppression reason}.
+ */
+ @PlaybackSuppressionReason
+ int getPlaybackSuppressionReason();
+
+ /**
+ * Returns whether the player is playing, i.e. {@link #getContentPosition()} is advancing.
+ *
+ * <p>If {@code false}, then at least one of the following is true:
+ *
+ * <ul>
+ * <li>The {@link #getPlaybackState() playback state} is not {@link #STATE_READY ready}.
+ * <li>There is no {@link #getPlayWhenReady() intention to play}.
+ * <li>Playback is {@link #getPlaybackSuppressionReason() suppressed for other reasons}.
+ * </ul>
+ *
+ * @return Whether the player is playing.
+ */
+ boolean isPlaying();
+
+ /**
+ * Returns the error that caused playback to fail. This is the same error that will have been
+ * reported via {@link Player.EventListener#onPlayerError(ExoPlaybackException)} at the time of
+ * failure. It can be queried using this method until {@code stop(true)} is called or the player
+ * is re-prepared.
+ *
+ * <p>Note that this method will always return {@code null} if {@link #getPlaybackState()} is not
+ * {@link #STATE_IDLE}.
+ *
+ * @return The error, or {@code null}.
+ */
+ @Nullable
+ ExoPlaybackException getPlaybackError();
+
+ /**
+ * Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
+ * <p>
+ * If the player is already in the ready state then this method can be used to pause and resume
+ * playback.
+ *
+ * @param playWhenReady Whether playback should proceed when ready.
+ */
+ void setPlayWhenReady(boolean playWhenReady);
+
+ /**
+ * Whether playback will proceed when {@link #getPlaybackState()} == {@link #STATE_READY}.
+ *
+ * @return Whether playback will proceed when ready.
+ */
+ boolean getPlayWhenReady();
+
+ /**
+ * Sets the {@link RepeatMode} to be used for playback.
+ *
+ * @param repeatMode The repeat mode.
+ */
+ void setRepeatMode(@RepeatMode int repeatMode);
+
+ /**
+ * Returns the current {@link RepeatMode} used for playback.
+ *
+ * @return The current repeat mode.
+ */
+ @RepeatMode int getRepeatMode();
+
+ /**
+ * Sets whether shuffling of windows is enabled.
+ *
+ * @param shuffleModeEnabled Whether shuffling is enabled.
+ */
+ void setShuffleModeEnabled(boolean shuffleModeEnabled);
+
+ /**
+ * Returns whether shuffling of windows is enabled.
+ */
+ boolean getShuffleModeEnabled();
+
+ /**
+ * Whether the player is currently loading the source.
+ *
+ * @return Whether the player is currently loading the source.
+ */
+ boolean isLoading();
+
+ /**
+ * Seeks to the default position associated with the current window. The position can depend on
+ * the type of media being played. For live streams it will typically be the live edge of the
+ * window. For other streams it will typically be the start of the window.
+ */
+ void seekToDefaultPosition();
+
+ /**
+ * Seeks to the default position associated with the specified window. The position can depend on
+ * the type of media being played. For live streams it will typically be the live edge of the
+ * window. For other streams it will typically be the start of the window.
+ *
+ * @param windowIndex The index of the window whose associated default position should be seeked
+ * to.
+ */
+ void seekToDefaultPosition(int windowIndex);
+
+ /**
+ * Seeks to a position specified in milliseconds in the current window.
+ *
+ * @param positionMs The seek position in the current window, or {@link C#TIME_UNSET} to seek to
+ * the window's default position.
+ */
+ void seekTo(long positionMs);
+
+ /**
+ * Seeks to a position specified in milliseconds in the specified window.
+ *
+ * @param windowIndex The index of the window.
+ * @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek to
+ * the window's default position.
+ * @throws IllegalSeekPositionException If the player has a non-empty timeline and the provided
+ * {@code windowIndex} is not within the bounds of the current timeline.
+ */
+ void seekTo(int windowIndex, long positionMs);
+
+ /**
+ * Returns whether a previous window exists, which may depend on the current repeat mode and
+ * whether shuffle mode is enabled.
+ */
+ boolean hasPrevious();
+
+ /**
+ * Seeks to the default position of the previous window in the timeline, which may depend on the
+ * current repeat mode and whether shuffle mode is enabled. Does nothing if {@link #hasPrevious()}
+ * is {@code false}.
+ */
+ void previous();
+
+ /**
+ * Returns whether a next window exists, which may depend on the current repeat mode and whether
+ * shuffle mode is enabled.
+ */
+ boolean hasNext();
+
+ /**
+ * Seeks to the default position of the next window in the timeline, which may depend on the
+ * current repeat mode and whether shuffle mode is enabled. Does nothing if {@link #hasNext()} is
+ * {@code false}.
+ */
+ void next();
+
+ /**
+ * Attempts to set the playback parameters. Passing {@code null} sets the parameters to the
+ * default, {@link PlaybackParameters#DEFAULT}, which means there is no speed or pitch adjustment.
+ *
+ * <p>Playback parameters changes may cause the player to buffer. {@link
+ * EventListener#onPlaybackParametersChanged(PlaybackParameters)} will be called whenever the
+ * currently active playback parameters change.
+ *
+ * @param playbackParameters The playback parameters, or {@code null} to use the defaults.
+ */
+ void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters);
+
+ /**
+ * Returns the currently active playback parameters.
+ *
+ * @see EventListener#onPlaybackParametersChanged(PlaybackParameters)
+ */
+ PlaybackParameters getPlaybackParameters();
+
+ /**
+ * Stops playback without resetting the player. Use {@code setPlayWhenReady(false)} rather than
+ * this method if the intention is to pause playback.
+ *
+ * <p>Calling this method will cause the playback state to transition to {@link #STATE_IDLE}. The
+ * player instance can still be used, and {@link #release()} must still be called on the player if
+ * it's no longer required.
+ *
+ * <p>Calling this method does not reset the playback position.
+ */
+ void stop();
+
+ /**
+ * Stops playback and optionally resets the player. Use {@code setPlayWhenReady(false)} rather
+ * than this method if the intention is to pause playback.
+ *
+ * <p>Calling this method will cause the playback state to transition to {@link #STATE_IDLE}. The
+ * player instance can still be used, and {@link #release()} must still be called on the player if
+ * it's no longer required.
+ *
+ * @param reset Whether the player should be reset.
+ */
+ void stop(boolean reset);
+
+ /**
+ * Releases the player. This method must be called when the player is no longer required. The
+ * player must not be used after calling this method.
+ */
+ void release();
+
+ /**
+ * Returns the number of renderers.
+ */
+ int getRendererCount();
+
+ /**
+ * Returns the track type that the renderer at a given index handles.
+ *
+ * @see Renderer#getTrackType()
+ * @param index The index of the renderer.
+ * @return One of the {@code TRACK_TYPE_*} constants defined in {@link C}.
+ */
+ int getRendererType(int index);
+
+ /**
+ * Returns the available track groups.
+ */
+ TrackGroupArray getCurrentTrackGroups();
+
+ /**
+ * Returns the current track selections for each renderer.
+ */
+ TrackSelectionArray getCurrentTrackSelections();
+
+ /**
+ * Returns the current manifest. The type depends on the type of media being played. May be null.
+ */
+ @Nullable Object getCurrentManifest();
+
+ /**
+ * Returns the current {@link Timeline}. Never null, but may be empty.
+ */
+ Timeline getCurrentTimeline();
+
+ /**
+ * Returns the index of the period currently being played.
+ */
+ int getCurrentPeriodIndex();
+
+ /**
+ * Returns the index of the window currently being played.
+ */
+ int getCurrentWindowIndex();
+
+ /**
+ * Returns the index of the next timeline window to be played, which may depend on the current
+ * repeat mode and whether shuffle mode is enabled. Returns {@link C#INDEX_UNSET} if the window
+ * currently being played is the last window.
+ */
+ int getNextWindowIndex();
+
+ /**
+ * Returns the index of the previous timeline window to be played, which may depend on the current
+ * repeat mode and whether shuffle mode is enabled. Returns {@link C#INDEX_UNSET} if the window
+ * currently being played is the first window.
+ */
+ int getPreviousWindowIndex();
+
+ /**
+ * Returns the tag of the currently playing window in the timeline. May be null if no tag is set
+ * or the timeline is not yet available.
+ */
+ @Nullable Object getCurrentTag();
+
+ /**
+ * Returns the duration of the current content window or ad in milliseconds, or {@link
+ * C#TIME_UNSET} if the duration is not known.
+ */
+ long getDuration();
+
+ /** Returns the playback position in the current content window or ad, in milliseconds. */
+ long getCurrentPosition();
+
+ /**
+ * Returns an estimate of the position in the current content window or ad up to which data is
+ * buffered, in milliseconds.
+ */
+ long getBufferedPosition();
+
+ /**
+ * Returns an estimate of the percentage in the current content window or ad up to which data is
+ * buffered, or 0 if no estimate is available.
+ */
+ int getBufferedPercentage();
+
+ /**
+ * Returns an estimate of the total buffered duration from the current position, in milliseconds.
+ * This includes pre-buffered data for subsequent ads and windows.
+ */
+ long getTotalBufferedDuration();
+
+ /**
+ * Returns whether the current window is dynamic, or {@code false} if the {@link Timeline} is
+ * empty.
+ *
+ * @see Timeline.Window#isDynamic
+ */
+ boolean isCurrentWindowDynamic();
+
+ /**
+ * Returns whether the current window is live, or {@code false} if the {@link Timeline} is empty.
+ *
+ * @see Timeline.Window#isLive
+ */
+ boolean isCurrentWindowLive();
+
+ /**
+ * Returns whether the current window is seekable, or {@code false} if the {@link Timeline} is
+ * empty.
+ *
+ * @see Timeline.Window#isSeekable
+ */
+ boolean isCurrentWindowSeekable();
+
+ /**
+ * Returns whether the player is currently playing an ad.
+ */
+ boolean isPlayingAd();
+
+ /**
+ * If {@link #isPlayingAd()} returns true, returns the index of the ad group in the period
+ * currently being played. Returns {@link C#INDEX_UNSET} otherwise.
+ */
+ int getCurrentAdGroupIndex();
+
+ /**
+ * If {@link #isPlayingAd()} returns true, returns the index of the ad in its ad group. Returns
+ * {@link C#INDEX_UNSET} otherwise.
+ */
+ int getCurrentAdIndexInAdGroup();
+
+ /**
+ * If {@link #isPlayingAd()} returns {@code true}, returns the duration of the current content
+ * window in milliseconds, or {@link C#TIME_UNSET} if the duration is not known. If there is no ad
+ * playing, the returned duration is the same as that returned by {@link #getDuration()}.
+ */
+ long getContentDuration();
+
+ /**
+ * If {@link #isPlayingAd()} returns {@code true}, returns the content position that will be
+ * played once all ads in the ad group have finished playing, in milliseconds. If there is no ad
+ * playing, the returned position is the same as that returned by {@link #getCurrentPosition()}.
+ */
+ long getContentPosition();
+
+ /**
+ * If {@link #isPlayingAd()} returns {@code true}, returns an estimate of the content position in
+ * the current content window up to which data is buffered, in milliseconds. If there is no ad
+ * playing, the returned position is the same as that returned by {@link #getBufferedPosition()}.
+ */
+ long getContentBufferedPosition();
+}