/* * Copyright (C) 2016 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 com.google.android.exoplayer2; import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; import com.google.android.exoplayer2.metadata.MetadataRenderer; import com.google.android.exoplayer2.source.ConcatenatingMediaSource; import com.google.android.exoplayer2.source.ExtractorMediaSource; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MergingMediaSource; import com.google.android.exoplayer2.source.SingleSampleMediaSource; import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.text.TextRenderer; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.video.MediaCodecVideoRenderer; /** * An extensible media player exposing traditional high-level media player functionality, such as * the ability to buffer media, play, pause and seek. Instances can be obtained from * {@link ExoPlayerFactory}. * *
ExoPlayer is designed to make few assumptions about (and hence impose few restrictions on) the * type of the media being played, how and where it is stored, and how it is rendered. Rather than * implementing the loading and rendering of media directly, ExoPlayer implementations delegate this * work to components that are injected when a player is created or when it's prepared for playback. * Components common to all ExoPlayer implementations are: *
An ExoPlayer can be built using the default components provided by the library, but may also * be built using custom implementations if non-standard behaviors are required. For example a * custom LoadControl could be injected to change the player's buffering strategy, or a custom * Renderer could be injected to use a video codec not supported natively by Android. * *
The concept of injecting components that implement pieces of player functionality is present * throughout the library. The default component implementations listed above delegate work to * further injected components. This allows many sub-components to be individually replaced with * custom implementations. For example the default MediaSource implementations require one or more * {@link DataSource} factories to be injected via their constructors. By providing a custom factory * it's possible to load data from a non-standard source or through a different network stack. * *
The figure below shows ExoPlayer's threading model.
*
*
*
* Messages can be delivered to a component via {@link #sendMessages} and * {@link #blockingSendMessages}. */ interface ExoPlayerComponent { /** * Handles a message delivered to the component. Called on the playback thread. * * @param messageType The message type. * @param message The message. * @throws ExoPlaybackException If an error occurred whilst handling the message. */ void handleMessage(int messageType, Object message) throws ExoPlaybackException; } /** * Defines a message and a target {@link ExoPlayerComponent} to receive it. */ final class ExoPlayerMessage { /** * The target to receive the message. */ public final ExoPlayerComponent target; /** * The type of the message. */ public final int messageType; /** * The message. */ public final Object message; /** * @param target The target of the message. * @param messageType The message type. * @param message The message. */ public ExoPlayerMessage(ExoPlayerComponent target, int messageType, Object message) { this.target = target; this.messageType = messageType; this.message = message; } } /** * The player does not have a source to play, so it is neither buffering nor ready to play. */ int STATE_IDLE = 1; /** * The player not able to immediately play from the current position. The cause is * {@link Renderer} specific, but this state typically occurs when more data needs to be * loaded to be ready to play, or more data needs to be buffered for playback to resume. */ int STATE_BUFFERING = 2; /** * The player is able to immediately play from the current position. The player will be playing if * {@link #getPlayWhenReady()} returns true, and paused otherwise. */ int STATE_READY = 3; /** * The player has finished playing the media. */ int STATE_ENDED = 4; /** * 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. * * @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 state of the player. * * @return One of the {@code STATE} constants defined in this interface. */ int getPlaybackState(); /** * Prepares the player to play the provided {@link MediaSource}. Equivalent to * {@code prepare(mediaSource, true, true)}. */ void prepare(MediaSource mediaSource); /** * Prepares the player to play the provided {@link MediaSource}, optionally resetting the playback * position the default position in the first {@link Timeline.Window}. * * @param mediaSource The {@link MediaSource} to play. * @param resetPosition Whether the playback position should be reset to the default position in * the first {@link Timeline.Window}. If false, playback will start from the position defined * by {@link #getCurrentWindowIndex()} and {@link #getCurrentPosition()}. * @param resetState Whether the timeline, manifest, tracks and track selections should be reset. * Should be true unless the player is being prepared to play the same media as it was playing * previously (e.g. if playback failed and is being retried). */ void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState); /** * Sets whether playback should proceed when {@link #getPlaybackState()} == {@link #STATE_READY}. *
* 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(); /** * 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 source passed to {@link #prepare(MediaSource)}. 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 source passed to {@link #prepare(MediaSource)}. 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 windowPositionMs The seek position in the current window. */ void seekTo(long windowPositionMs); /** * Seeks to a position specified in milliseconds in the specified window. * * @param windowIndex The index of the window. * @param windowPositionMs The seek position in the specified window. */ void seekTo(int windowIndex, long windowPositionMs); /** * Stops playback. Use {@code setPlayWhenReady(false)} rather than this method if the intention * is to pause playback. *
* 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. *
* Calling this method does not reset the playback position. */ void stop(); /** * 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(); /** * Sends messages to their target components. The messages are delivered on the playback thread. * If a component throws an {@link ExoPlaybackException} then it is propagated out of the player * as an error. * * @param messages The messages to be sent. */ void sendMessages(ExoPlayerMessage... messages); /** * Variant of {@link #sendMessages(ExoPlayerMessage...)} that blocks until after the messages have * been delivered. * * @param messages The messages to be sent. */ void blockingSendMessages(ExoPlayerMessage... messages); /** * 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 {@link MediaSource} passed to * {@link #prepare}. */ Object getCurrentManifest(); /** * Returns the current {@link Timeline}, or {@code null} if there is no timeline. */ Timeline getCurrentTimeline(); /** * Returns the index of the period currently being played, or {@link C#INDEX_UNSET} if unknown. */ int getCurrentPeriodIndex(); /** * Returns the index of the window currently being played. */ int getCurrentWindowIndex(); /** * Returns the duration of the current window in milliseconds, or {@link C#TIME_UNSET} if the * duration is not known. */ long getDuration(); /** * Returns the playback position in the current window, in milliseconds. */ long getCurrentPosition(); /** * Returns an estimate of the position in the current window up to which data is buffered, in * milliseconds. */ long getBufferedPosition(); /** * Returns an estimate of the percentage in the current window up to which data is buffered, or 0 * if no estimate is available. */ int getBufferedPercentage(); }