public interface ExoPlayer
Topics covered here are:
The implementation is designed to make no assumptions about (and hence impose no restrictions
on) the type of the media being played, how and where it is stored, or how it is rendered.
Rather than implementing the loading and rendering of media directly, ExoPlayer
instead
delegates this work to one or more TrackRenderer
s, which are injected when the player
is prepared. Hence ExoPlayer
is capable of loading and playing any media for which a
TrackRenderer
implementation can be provided.
MediaCodecAudioTrackRenderer
and MediaCodecVideoTrackRenderer
can be used for
the common cases of rendering audio and video. These components in turn require an
upstream SampleSource
to be injected through their constructors, where upstream
is defined to denote a component that is closer to the source of the media. This pattern of
upstream dependency injection is actively encouraged, since it means that the functionality of
the player is built up through the composition of components that can easily be exchanged for
alternate implementations. For example a SampleSource
implementation may require a
further upstream data loading component to be injected through its constructor, with different
implementations enabling the loading of data from various sources.
The figure below shows the ExoPlayer
threading model.
ExoPlayer.Listener
s are invoked on the thread that created the ExoPlayer
instance.TrackRenderer
s in order to load and play the media.TrackRenderer
implementations (or any upstream components that they depend on) may
use additional background threads (e.g. to load data). These are implementation specific.The components of an ExoPlayer
's state can be divided into two distinct groups. State
accessed by getSelectedTrack(int)
and getPlayWhenReady()
is only ever
changed by invoking the player's methods, and are never changed as a result of operations that
have been performed asynchronously by the playback thread. In contrast, the playback state
accessed by getPlaybackState()
is only ever changed as a result of operations
completing on the playback thread, as illustrated below.
The possible playback state transitions are shown below. Transitions can be triggered either
by changes in the state of the TrackRenderer
s being used, or as a result of
prepare(TrackRenderer[])
, stop()
or release()
being invoked.
Modifier and Type | Interface and Description |
---|---|
static interface |
ExoPlayer.ExoPlayerComponent
A component of an
ExoPlayer that can receive messages on the playback thread. |
static class |
ExoPlayer.Factory
A factory for instantiating ExoPlayer instances.
|
static interface |
ExoPlayer.Listener
Interface definition for a callback to be notified of changes in player state.
|
Modifier and Type | Field and Description |
---|---|
static int |
STATE_BUFFERING
The player is prepared but not able to immediately play from the current position.
|
static int |
STATE_ENDED
The player has finished playing the media.
|
static int |
STATE_IDLE
The player is neither prepared or being prepared.
|
static int |
STATE_PREPARING
The player is being prepared.
|
static int |
STATE_READY
The player is prepared and able to immediately play from the current position.
|
static int |
TRACK_DEFAULT
A value that can be passed as the second argument to
setSelectedTrack(int, int) to
select the default track. |
static int |
TRACK_DISABLED
A value that can be passed as the second argument to
setSelectedTrack(int, int) to
disable the renderer. |
static long |
UNKNOWN_TIME
Represents an unknown time or duration.
|
Modifier and Type | Method and Description |
---|---|
void |
addListener(ExoPlayer.Listener listener)
Register a listener to receive events from the player.
|
void |
blockingSendMessage(ExoPlayer.ExoPlayerComponent target,
int messageType,
Object message)
Blocking variant of
sendMessage(ExoPlayerComponent, int, Object) that does not return
until after the message has been delivered. |
int |
getBufferedPercentage()
Gets an estimate of the percentage into the media up to which data is buffered.
|
long |
getBufferedPosition()
Gets an estimate of the absolute position in milliseconds up to which data is buffered.
|
long |
getCurrentPosition()
Gets the current playback position in milliseconds.
|
long |
getDuration()
Gets the duration of the track in milliseconds.
|
Looper |
getPlaybackLooper()
Gets the
Looper associated with the playback thread. |
int |
getPlaybackState()
Returns the current state of the player.
|
boolean |
getPlayWhenReady()
Whether playback will proceed when
getPlaybackState() == STATE_READY . |
int |
getSelectedTrack(int rendererIndex)
Returns the index of the currently selected track for the specified renderer.
|
int |
getTrackCount(int rendererIndex)
Returns the number of tracks exposed by the specified renderer.
|
MediaFormat |
getTrackFormat(int rendererIndex,
int trackIndex)
Returns the format of a track.
|
boolean |
isPlayWhenReadyCommitted()
Whether the current value of
getPlayWhenReady() has been reflected by the
internal playback thread. |
void |
prepare(TrackRenderer... renderers)
Prepares the player for playback.
|
void |
release()
Releases the player.
|
void |
removeListener(ExoPlayer.Listener listener)
Unregister a listener.
|
void |
seekTo(long positionMs)
Seeks to a position specified in milliseconds.
|
void |
sendMessage(ExoPlayer.ExoPlayerComponent target,
int messageType,
Object message)
Sends a message to a specified component.
|
void |
setPlayWhenReady(boolean playWhenReady)
Sets whether playback should proceed when
getPlaybackState() == STATE_READY . |
void |
setSelectedTrack(int rendererIndex,
int trackIndex)
Selects a track for the specified renderer.
|
void |
stop()
Stops playback.
|
static final int STATE_IDLE
static final int STATE_PREPARING
static final int STATE_BUFFERING
TrackRenderer
specific, but this state typically occurs when more data needs
to be buffered for playback to start.static final int STATE_READY
getPlayWhenReady()
returns true, and paused otherwise.static final int STATE_ENDED
static final int TRACK_DISABLED
setSelectedTrack(int, int)
to
disable the renderer.static final int TRACK_DEFAULT
setSelectedTrack(int, int)
to
select the default track.static final long UNKNOWN_TIME
Looper getPlaybackLooper()
Looper
associated with the playback thread.Looper
associated with the playback thread.void addListener(ExoPlayer.Listener listener)
listener
- The listener to register.void removeListener(ExoPlayer.Listener listener)
listener
- The listener to unregister.int getPlaybackState()
STATE
constants defined in this interface.void prepare(TrackRenderer... renderers)
renderers
- The TrackRenderer
s to use. The number of renderers must match the
value that was passed to the ExoPlayer.Factory.newInstance(int, int, int)
method.int getTrackCount(int rendererIndex)
rendererIndex
- The index of the renderer.MediaFormat getTrackFormat(int rendererIndex, int trackIndex)
rendererIndex
- The index of the renderer.trackIndex
- The index of the track.void setSelectedTrack(int rendererIndex, int trackIndex)
rendererIndex
- The index of the renderer.trackIndex
- The index of the track. A negative value or a value greater than or equal to
the renderer's track count will disable the renderer.int getSelectedTrack(int rendererIndex)
rendererIndex
- The index of the renderer.void setPlayWhenReady(boolean playWhenReady)
getPlaybackState()
== STATE_READY
.
If the player is already in this state, then this method can be used to pause and resume
playback.playWhenReady
- Whether playback should proceed when ready.boolean getPlayWhenReady()
getPlaybackState()
== STATE_READY
.boolean isPlayWhenReadyCommitted()
getPlayWhenReady()
has been reflected by the
internal playback thread.void seekTo(long positionMs)
positionMs
- The seek position.void stop()
setPlayWhenReady(false)
rather than this method if the intention
is to pause playback.
Calling this method will cause the playback state to transition to
STATE_IDLE
. The player instance can still be used, and
release()
must still be called on the player if it's no longer required.
Calling this method does not reset the playback position. If this player instance will be used
to play another video from its start, then seekTo(0)
should be called after stopping
the player and before preparing it for the next video.
void release()
The player must not be used after calling this method.
void sendMessage(ExoPlayer.ExoPlayerComponent target, int messageType, Object message)
ExoPlaybackException
, then it is
propagated out of the player as an error.target
- The target to which the message should be delivered.messageType
- An integer that can be used to identify the type of the message.message
- The message object.void blockingSendMessage(ExoPlayer.ExoPlayerComponent target, int messageType, Object message)
sendMessage(ExoPlayerComponent, int, Object)
that does not return
until after the message has been delivered.target
- The target to which the message should be delivered.messageType
- An integer that can be used to identify the type of the message.message
- The message object.long getDuration()
UNKNOWN_TIME
if the
duration is not known.long getCurrentPosition()
long getBufferedPosition()
UNKNOWN_TIME
if no estimate is available.int getBufferedPercentage()