mirror of
https://github.com/samsonjs/media.git
synced 2026-04-08 11:45:51 +00:00
Extract Player interface from ExoPlayer
This is the first step towards facilitating Cast integration to ExoPlayer. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=162366198
This commit is contained in:
parent
41028fafba
commit
4f5ac9e04f
11 changed files with 497 additions and 424 deletions
|
|
@ -39,6 +39,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
|||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player.EventListener;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
||||
|
|
@ -82,7 +83,7 @@ import java.util.UUID;
|
|||
/**
|
||||
* An activity that plays media using {@link SimpleExoPlayer}.
|
||||
*/
|
||||
public class PlayerActivity extends Activity implements OnClickListener, ExoPlayer.EventListener,
|
||||
public class PlayerActivity extends Activity implements OnClickListener, EventListener,
|
||||
PlaybackControlView.VisibilityListener {
|
||||
|
||||
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
|||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
|
|
@ -484,7 +485,7 @@ public final class MediaSessionConnector {
|
|||
Pair<Integer, String> message = errorMessageProvider.getErrorMessage(playbackException);
|
||||
builder.setErrorMessage(message.first, message.second);
|
||||
}
|
||||
if (player.getPlaybackState() != ExoPlayer.STATE_IDLE) {
|
||||
if (player.getPlaybackState() != Player.STATE_IDLE) {
|
||||
playbackException = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -507,7 +508,7 @@ public final class MediaSessionConnector {
|
|||
if (queue == null || queue.size() < 2) {
|
||||
removePlaybackActions(PlaybackStateCompat.ACTION_SKIP_TO_NEXT
|
||||
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS);
|
||||
} else if (player.getRepeatMode() != ExoPlayer.REPEAT_MODE_OFF) {
|
||||
} else if (player.getRepeatMode() != Player.REPEAT_MODE_OFF) {
|
||||
addPlaybackActions(PlaybackStateCompat.ACTION_SKIP_TO_NEXT
|
||||
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS);
|
||||
} else if (activeQueueItemId == queue.get(0).getQueueId()) {
|
||||
|
|
@ -576,11 +577,11 @@ public final class MediaSessionConnector {
|
|||
|
||||
private int mapPlaybackState(int exoPlayerPlaybackState, boolean playWhenReady) {
|
||||
switch (exoPlayerPlaybackState) {
|
||||
case ExoPlayer.STATE_BUFFERING:
|
||||
case Player.STATE_BUFFERING:
|
||||
return PlaybackStateCompat.STATE_BUFFERING;
|
||||
case ExoPlayer.STATE_READY:
|
||||
case Player.STATE_READY:
|
||||
return playWhenReady ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED;
|
||||
case ExoPlayer.STATE_ENDED:
|
||||
case Player.STATE_ENDED:
|
||||
return PlaybackStateCompat.STATE_PAUSED;
|
||||
default:
|
||||
return PlaybackStateCompat.STATE_NONE;
|
||||
|
|
@ -599,7 +600,7 @@ public final class MediaSessionConnector {
|
|||
return playbackPreparer != null && isActionPublished(action);
|
||||
}
|
||||
|
||||
private class ExoPlayerEventListener implements ExoPlayer.EventListener {
|
||||
private class ExoPlayerEventListener implements Player.EventListener {
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
if (queueNavigator != null) {
|
||||
|
|
@ -625,9 +626,9 @@ public final class MediaSessionConnector {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged(@ExoPlayer.RepeatMode int repeatMode) {
|
||||
mediaSession.setRepeatMode(repeatMode == ExoPlayer.REPEAT_MODE_ONE
|
||||
? PlaybackStateCompat.REPEAT_MODE_ONE : repeatMode == ExoPlayer.REPEAT_MODE_ALL
|
||||
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
|
||||
mediaSession.setRepeatMode(repeatMode == Player.REPEAT_MODE_ONE
|
||||
? PlaybackStateCompat.REPEAT_MODE_ONE : repeatMode == Player.REPEAT_MODE_ALL
|
||||
? PlaybackStateCompat.REPEAT_MODE_ALL : PlaybackStateCompat.REPEAT_MODE_NONE);
|
||||
updateMediaSessionPlaybackState();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import android.content.Context;
|
|||
import android.os.Bundle;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.util.RepeatModeUtil;
|
||||
|
||||
/**
|
||||
|
|
@ -81,15 +82,15 @@ public final class RepeatModeActionProvider implements MediaSessionConnector.Cus
|
|||
CharSequence actionLabel;
|
||||
int iconResourceId;
|
||||
switch (player.getRepeatMode()) {
|
||||
case ExoPlayer.REPEAT_MODE_ONE:
|
||||
case Player.REPEAT_MODE_ONE:
|
||||
actionLabel = repeatOneDescription;
|
||||
iconResourceId = R.drawable.exo_media_action_repeat_one;
|
||||
break;
|
||||
case ExoPlayer.REPEAT_MODE_ALL:
|
||||
case Player.REPEAT_MODE_ALL:
|
||||
actionLabel = repeatAllDescription;
|
||||
iconResourceId = R.drawable.exo_media_action_repeat_all;
|
||||
break;
|
||||
case ExoPlayer.REPEAT_MODE_OFF:
|
||||
case Player.REPEAT_MODE_OFF:
|
||||
default:
|
||||
actionLabel = repeatOffDescription;
|
||||
iconResourceId = R.drawable.exo_media_action_repeat_off;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.MediaSource.Listener;
|
||||
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
||||
|
|
@ -352,12 +353,12 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EventListener listener) {
|
||||
public void addListener(Player.EventListener listener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(EventListener listener) {
|
||||
public void removeListener(Player.EventListener listener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
package com.google.android.exoplayer2;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
||||
import com.google.android.exoplayer2.metadata.MetadataRenderer;
|
||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||
|
|
@ -25,15 +23,11 @@ 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.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;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* An extensible media player exposing traditional high-level media player functionality, such as
|
||||
|
|
@ -108,91 +102,13 @@ import java.lang.annotation.RetentionPolicy;
|
|||
* may use a background thread to load data. These are implementation specific.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface ExoPlayer {
|
||||
public interface ExoPlayer extends Player {
|
||||
|
||||
/**
|
||||
* Listener of changes in player state.
|
||||
* @deprecated Use {@link Player.EventListener} instead.
|
||||
*/
|
||||
interface EventListener {
|
||||
|
||||
/**
|
||||
* 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()}.
|
||||
*
|
||||
* @param timeline The latest timeline. Never null, but may be empty.
|
||||
* @param manifest The latest manifest. May be null.
|
||||
*/
|
||||
void onTimelineChanged(Timeline timeline, Object manifest);
|
||||
|
||||
/**
|
||||
* 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 {@link Renderer}. Never null and always
|
||||
* of length {@link #getRendererCount()}, but may contain null elements.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 One of the {@code STATE} constants defined in the {@link ExoPlayer}
|
||||
* interface.
|
||||
*/
|
||||
void onPlayerStateChanged(boolean playWhenReady, int playbackState);
|
||||
|
||||
/**
|
||||
* Called when the value of {@link #getRepeatMode()} changes.
|
||||
*
|
||||
* @param repeatMode The {@link RepeatMode} used for playback.
|
||||
*/
|
||||
void onRepeatModeChanged(@RepeatMode int repeatMode);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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, Object)} is called in this case.
|
||||
*/
|
||||
void onPositionDiscontinuity();
|
||||
|
||||
/**
|
||||
* Called when the current playback parameters change. The playback parameters may change due to
|
||||
* a call to {@link ExoPlayer#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.
|
||||
*/
|
||||
void onPlaybackParametersChanged(PlaybackParameters playbackParameters);
|
||||
|
||||
}
|
||||
@Deprecated
|
||||
interface EventListener extends Player.EventListener {}
|
||||
|
||||
/**
|
||||
* A component of an {@link ExoPlayer} that can receive messages on the playback thread.
|
||||
|
|
@ -245,43 +161,41 @@ public interface ExoPlayer {
|
|||
}
|
||||
|
||||
/**
|
||||
* The player does not have a source to play, so it is neither buffering nor ready to play.
|
||||
* @deprecated Use {@link Player#STATE_IDLE} instead.
|
||||
*/
|
||||
int STATE_IDLE = 1;
|
||||
@Deprecated
|
||||
int STATE_IDLE = Player.STATE_IDLE;
|
||||
/**
|
||||
* 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.
|
||||
* @deprecated Use {@link Player#STATE_BUFFERING} instead.
|
||||
*/
|
||||
int STATE_BUFFERING = 2;
|
||||
@Deprecated
|
||||
int STATE_BUFFERING = Player.STATE_BUFFERING;
|
||||
/**
|
||||
* The player is able to immediately play from the current position. The player will be playing if
|
||||
* {@link #getPlayWhenReady()} returns true, and paused otherwise.
|
||||
* @deprecated Use {@link Player#STATE_READY} instead.
|
||||
*/
|
||||
int STATE_READY = 3;
|
||||
@Deprecated
|
||||
int STATE_READY = Player.STATE_READY;
|
||||
/**
|
||||
* The player has finished playing the media.
|
||||
* @deprecated Use {@link Player#STATE_ENDED} instead.
|
||||
*/
|
||||
int STATE_ENDED = 4;
|
||||
@Deprecated
|
||||
int STATE_ENDED = Player.STATE_ENDED;
|
||||
|
||||
/**
|
||||
* Repeat modes for playback.
|
||||
* @deprecated Use {@link Player#REPEAT_MODE_OFF} instead.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({REPEAT_MODE_OFF, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
|
||||
public @interface RepeatMode {}
|
||||
@Deprecated
|
||||
@RepeatMode int REPEAT_MODE_OFF = Player.REPEAT_MODE_OFF;
|
||||
/**
|
||||
* Normal playback without repetition.
|
||||
* @deprecated Use {@link Player#REPEAT_MODE_ONE} instead.
|
||||
*/
|
||||
int REPEAT_MODE_OFF = 0;
|
||||
@Deprecated
|
||||
@RepeatMode int REPEAT_MODE_ONE = Player.REPEAT_MODE_ONE;
|
||||
/**
|
||||
* "Repeat One" mode to repeat the currently playing window infinitely.
|
||||
* @deprecated Use {@link Player#REPEAT_MODE_ALL} instead.
|
||||
*/
|
||||
int REPEAT_MODE_ONE = 1;
|
||||
/**
|
||||
* "Repeat All" mode to repeat the entire timeline infinitely.
|
||||
*/
|
||||
int REPEAT_MODE_ALL = 2;
|
||||
@Deprecated
|
||||
@RepeatMode int REPEAT_MODE_ALL = Player.REPEAT_MODE_ALL;
|
||||
|
||||
/**
|
||||
* Gets the {@link Looper} associated with the playback thread.
|
||||
|
|
@ -290,29 +204,6 @@ public interface ExoPlayer {
|
|||
*/
|
||||
Looper getPlaybackLooper();
|
||||
|
||||
/**
|
||||
* 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 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)}.
|
||||
|
|
@ -333,118 +224,6 @@ public interface ExoPlayer {
|
|||
*/
|
||||
void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState);
|
||||
|
||||
/**
|
||||
* 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 A repeat mode.
|
||||
*/
|
||||
void setRepeatMode(@RepeatMode int repeatMode);
|
||||
|
||||
/**
|
||||
* Returns the current {@link RepeatMode} used for playback.
|
||||
*
|
||||
* @return The current repeat mode.
|
||||
*/
|
||||
@RepeatMode int getRepeatMode();
|
||||
|
||||
/**
|
||||
* 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 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.
|
||||
*/
|
||||
void seekTo(int windowIndex, long positionMs);
|
||||
|
||||
/**
|
||||
* 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. When that listener is called, the parameters
|
||||
* passed to it may not match {@code playbackParameters}. For example, the chosen speed or pitch
|
||||
* may be out of range, in which case they are constrained to a set of permitted values. If it is
|
||||
* not possible to change the playback parameters, the listener will not be invoked.
|
||||
*
|
||||
* @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. 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();
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -462,112 +241,4 @@ public interface ExoPlayer {
|
|||
*/
|
||||
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}. May be null.
|
||||
*/
|
||||
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 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();
|
||||
|
||||
/**
|
||||
* 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 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 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();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
private final TrackSelectionArray emptyTrackSelections;
|
||||
private final Handler eventHandler;
|
||||
private final ExoPlayerImplInternal internalPlayer;
|
||||
private final CopyOnWriteArraySet<EventListener> listeners;
|
||||
private final CopyOnWriteArraySet<Player.EventListener> listeners;
|
||||
private final Timeline.Window window;
|
||||
private final Timeline.Period period;
|
||||
|
||||
|
|
@ -114,12 +114,12 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EventListener listener) {
|
||||
public void addListener(Player.EventListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(EventListener listener) {
|
||||
public void removeListener(Player.EventListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
if (!timeline.isEmpty() || manifest != null) {
|
||||
timeline = Timeline.EMPTY;
|
||||
manifest = null;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onTimelineChanged(timeline, manifest);
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
trackGroups = TrackGroupArray.EMPTY;
|
||||
trackSelections = emptyTrackSelections;
|
||||
trackSelector.onSelectionActivated(null);
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onTracksChanged(trackGroups, trackSelections);
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
if (this.playWhenReady != playWhenReady) {
|
||||
this.playWhenReady = playWhenReady;
|
||||
internalPlayer.setPlayWhenReady(playWhenReady);
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPlayerStateChanged(playWhenReady, playbackState);
|
||||
}
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
if (this.repeatMode != repeatMode) {
|
||||
this.repeatMode = repeatMode;
|
||||
internalPlayer.setRepeatMode(repeatMode);
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onRepeatModeChanged(repeatMode);
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
} else {
|
||||
maskingWindowPositionMs = positionMs;
|
||||
internalPlayer.seekTo(timeline, windowIndex, C.msToUs(positionMs));
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPositionDiscontinuity();
|
||||
}
|
||||
}
|
||||
|
|
@ -420,14 +420,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
}
|
||||
case ExoPlayerImplInternal.MSG_STATE_CHANGED: {
|
||||
playbackState = msg.arg1;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPlayerStateChanged(playWhenReady, playbackState);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ExoPlayerImplInternal.MSG_LOADING_CHANGED: {
|
||||
isLoading = msg.arg1 != 0;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onLoadingChanged(isLoading);
|
||||
}
|
||||
break;
|
||||
|
|
@ -439,7 +439,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
trackGroups = trackSelectorResult.groups;
|
||||
trackSelections = trackSelectorResult.selections;
|
||||
trackSelector.onSelectionActivated(trackSelectorResult.info);
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onTracksChanged(trackGroups, trackSelections);
|
||||
}
|
||||
}
|
||||
|
|
@ -449,7 +449,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
if (--pendingSeekAcks == 0) {
|
||||
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
|
||||
if (msg.arg1 != 0) {
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPositionDiscontinuity();
|
||||
}
|
||||
}
|
||||
|
|
@ -459,7 +459,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
case ExoPlayerImplInternal.MSG_POSITION_DISCONTINUITY: {
|
||||
if (pendingSeekAcks == 0) {
|
||||
playbackInfo = (ExoPlayerImplInternal.PlaybackInfo) msg.obj;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPositionDiscontinuity();
|
||||
}
|
||||
}
|
||||
|
|
@ -472,7 +472,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
timeline = sourceInfo.timeline;
|
||||
manifest = sourceInfo.manifest;
|
||||
playbackInfo = sourceInfo.playbackInfo;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onTimelineChanged(timeline, manifest);
|
||||
}
|
||||
}
|
||||
|
|
@ -482,7 +482,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
PlaybackParameters playbackParameters = (PlaybackParameters) msg.obj;
|
||||
if (!this.playbackParameters.equals(playbackParameters)) {
|
||||
this.playbackParameters = playbackParameters;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPlaybackParametersChanged(playbackParameters);
|
||||
}
|
||||
}
|
||||
|
|
@ -490,7 +490,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
}
|
||||
case ExoPlayerImplInternal.MSG_ERROR: {
|
||||
ExoPlaybackException exception = (ExoPlaybackException) msg.obj;
|
||||
for (EventListener listener : listeners) {
|
||||
for (Player.EventListener listener : listeners) {
|
||||
listener.onPlayerError(exception);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
package com.google.android.exoplayer2;
|
||||
|
||||
import android.util.Pair;
|
||||
import com.google.android.exoplayer2.ExoPlayer.RepeatMode;
|
||||
import com.google.android.exoplayer2.ExoPlayerImplInternal.PlaybackInfo;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* 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 com.google.android.exoplayer2;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* An interface for media players.
|
||||
*/
|
||||
public interface Player {
|
||||
|
||||
/**
|
||||
* Listener of changes in player state.
|
||||
*/
|
||||
interface EventListener {
|
||||
|
||||
/**
|
||||
* 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()}.
|
||||
*
|
||||
* @param timeline The latest timeline. Never null, but may be empty.
|
||||
* @param manifest The latest manifest. May be null.
|
||||
*/
|
||||
void onTimelineChanged(Timeline timeline, Object manifest);
|
||||
|
||||
/**
|
||||
* 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 {@link Renderer}. Never null and always
|
||||
* of length {@link #getRendererCount()}, but may contain null elements.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 One of the {@code STATE} constants.
|
||||
*/
|
||||
void onPlayerStateChanged(boolean playWhenReady, int playbackState);
|
||||
|
||||
/**
|
||||
* Called when the value of {@link #getRepeatMode()} changes.
|
||||
*
|
||||
* @param repeatMode The {@link RepeatMode} used for playback.
|
||||
*/
|
||||
void onRepeatModeChanged(@RepeatMode int repeatMode);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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, Object)} is called in this case.
|
||||
*/
|
||||
void onPositionDiscontinuity();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void onPlaybackParametersChanged(PlaybackParameters playbackParameters);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Repeat modes for playback.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({REPEAT_MODE_OFF, REPEAT_MODE_ONE, REPEAT_MODE_ALL})
|
||||
public @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;
|
||||
|
||||
/**
|
||||
* 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 state of the player.
|
||||
*
|
||||
* @return One of the {@code STATE} constants defined in this interface.
|
||||
*/
|
||||
int getPlaybackState();
|
||||
|
||||
/**
|
||||
* 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 A repeat mode.
|
||||
*/
|
||||
void setRepeatMode(@RepeatMode int repeatMode);
|
||||
|
||||
/**
|
||||
* Returns the current {@link RepeatMode} used for playback.
|
||||
*
|
||||
* @return The current repeat mode.
|
||||
*/
|
||||
@RepeatMode int getRepeatMode();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void seekTo(int windowIndex, long positionMs);
|
||||
|
||||
/**
|
||||
* 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. When that listener is called, the parameters
|
||||
* passed to it may not match {@code playbackParameters}. For example, the chosen speed or pitch
|
||||
* may be out of range, in which case they are constrained to a set of permitted values. If it is
|
||||
* not possible to change the playback parameters, the listener will not be invoked.
|
||||
*
|
||||
* @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. 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();
|
||||
|
||||
/**
|
||||
* 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 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();
|
||||
|
||||
/**
|
||||
* 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 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 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();
|
||||
|
||||
}
|
||||
|
|
@ -524,12 +524,12 @@ public class SimpleExoPlayer implements ExoPlayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EventListener listener) {
|
||||
public void addListener(Player.EventListener listener) {
|
||||
player.addListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(EventListener listener) {
|
||||
public void removeListener(Player.EventListener listener) {
|
||||
player.removeListener(listener);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ package com.google.android.exoplayer2.source;
|
|||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayer.RepeatMode;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
|
|
@ -45,7 +46,7 @@ import java.util.Formatter;
|
|||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A view for controlling {@link ExoPlayer} instances.
|
||||
* A view for controlling {@link Player} instances.
|
||||
* <p>
|
||||
* A PlaybackControlView can be customized by setting attributes (or calling corresponding methods),
|
||||
* overriding the view's layout file or by specifying a custom view layout file, as outlined below.
|
||||
|
|
@ -183,7 +184,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Dispatches operations to the player.
|
||||
* Dispatches operations to the {@link Player}.
|
||||
* <p>
|
||||
* Implementations may choose to suppress (e.g. prevent playback from resuming if audio focus is
|
||||
* denied) or modify (e.g. change the seek position to prevent a user from seeking past a
|
||||
|
|
@ -192,33 +193,34 @@ public class PlaybackControlView extends FrameLayout {
|
|||
public interface ControlDispatcher {
|
||||
|
||||
/**
|
||||
* Dispatches a {@link ExoPlayer#setPlayWhenReady(boolean)} operation.
|
||||
* Dispatches a {@link Player#setPlayWhenReady(boolean)} operation.
|
||||
*
|
||||
* @param player The player to which the operation should be dispatched.
|
||||
* @param player The {@link Player} to which the operation should be dispatched.
|
||||
* @param playWhenReady Whether playback should proceed when ready.
|
||||
* @return True if the operation was dispatched. False if suppressed.
|
||||
*/
|
||||
boolean dispatchSetPlayWhenReady(ExoPlayer player, boolean playWhenReady);
|
||||
boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady);
|
||||
|
||||
/**
|
||||
* Dispatches a {@link ExoPlayer#seekTo(int, long)} operation.
|
||||
* Dispatches a {@link Player#seekTo(int, long)} operation.
|
||||
*
|
||||
* @param player The player to which the operation should be dispatched.
|
||||
* @param player The {@link Player} to which the operation should be dispatched.
|
||||
* @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.
|
||||
* @return True if the operation was dispatched. False if suppressed.
|
||||
*/
|
||||
boolean dispatchSeekTo(ExoPlayer player, int windowIndex, long positionMs);
|
||||
boolean dispatchSeekTo(Player player, int windowIndex, long positionMs);
|
||||
|
||||
/**
|
||||
* Dispatches a {@link ExoPlayer#setRepeatMode(int)} operation.
|
||||
* Dispatches a {@link Player#setRepeatMode(int)} operation.
|
||||
*
|
||||
* @param player The player to which the operation should be dispatched.
|
||||
* @param player The {@link Player} to which the operation should be dispatched.
|
||||
* @param repeatMode The repeat mode.
|
||||
* @return True if the operation was dispatched. False if suppressed.
|
||||
*/
|
||||
boolean dispatchSetRepeatMode(ExoPlayer player, @ExoPlayer.RepeatMode int repeatMode);
|
||||
boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -228,19 +230,19 @@ public class PlaybackControlView extends FrameLayout {
|
|||
public static final ControlDispatcher DEFAULT_CONTROL_DISPATCHER = new ControlDispatcher() {
|
||||
|
||||
@Override
|
||||
public boolean dispatchSetPlayWhenReady(ExoPlayer player, boolean playWhenReady) {
|
||||
public boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady) {
|
||||
player.setPlayWhenReady(playWhenReady);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchSeekTo(ExoPlayer player, int windowIndex, long positionMs) {
|
||||
public boolean dispatchSeekTo(Player player, int windowIndex, long positionMs) {
|
||||
player.seekTo(windowIndex, positionMs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchSetRepeatMode(ExoPlayer player, @ExoPlayer.RepeatMode int repeatMode) {
|
||||
public boolean dispatchSetRepeatMode(Player player, @RepeatMode int repeatMode) {
|
||||
player.setRepeatMode(repeatMode);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -283,7 +285,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||
private final String repeatOneButtonContentDescription;
|
||||
private final String repeatAllButtonContentDescription;
|
||||
|
||||
private ExoPlayer player;
|
||||
private Player player;
|
||||
private ControlDispatcher controlDispatcher;
|
||||
private VisibilityListener visibilityListener;
|
||||
|
||||
|
|
@ -409,18 +411,19 @@ public class PlaybackControlView extends FrameLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the player currently being controlled by this view, or null if no player is set.
|
||||
* Returns the {@link Player} currently being controlled by this view, or null if no player is
|
||||
* set.
|
||||
*/
|
||||
public ExoPlayer getPlayer() {
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ExoPlayer} to control.
|
||||
* Sets the {@link Player} to control.
|
||||
*
|
||||
* @param player The {@code ExoPlayer} to control.
|
||||
* @param player The {@link Player} to control.
|
||||
*/
|
||||
public void setPlayer(ExoPlayer player) {
|
||||
public void setPlayer(Player player) {
|
||||
if (this.player == player) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -528,16 +531,16 @@ public class PlaybackControlView extends FrameLayout {
|
|||
public void setRepeatToggleModes(@RepeatModeUtil.RepeatToggleModes int repeatToggleModes) {
|
||||
this.repeatToggleModes = repeatToggleModes;
|
||||
if (player != null) {
|
||||
@ExoPlayer.RepeatMode int currentMode = player.getRepeatMode();
|
||||
@Player.RepeatMode int currentMode = player.getRepeatMode();
|
||||
if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_NONE
|
||||
&& currentMode != ExoPlayer.REPEAT_MODE_OFF) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_OFF);
|
||||
&& currentMode != Player.REPEAT_MODE_OFF) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_OFF);
|
||||
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ONE
|
||||
&& currentMode == ExoPlayer.REPEAT_MODE_ALL) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_ONE);
|
||||
&& currentMode == Player.REPEAT_MODE_ALL) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ONE);
|
||||
} else if (repeatToggleModes == RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL
|
||||
&& currentMode == ExoPlayer.REPEAT_MODE_ONE) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, ExoPlayer.REPEAT_MODE_ALL);
|
||||
&& currentMode == Player.REPEAT_MODE_ONE) {
|
||||
controlDispatcher.dispatchSetRepeatMode(player, Player.REPEAT_MODE_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -658,15 +661,15 @@ public class PlaybackControlView extends FrameLayout {
|
|||
return;
|
||||
}
|
||||
switch (player.getRepeatMode()) {
|
||||
case ExoPlayer.REPEAT_MODE_OFF:
|
||||
case Player.REPEAT_MODE_OFF:
|
||||
repeatToggleButton.setImageDrawable(repeatOffButtonDrawable);
|
||||
repeatToggleButton.setContentDescription(repeatOffButtonContentDescription);
|
||||
break;
|
||||
case ExoPlayer.REPEAT_MODE_ONE:
|
||||
case Player.REPEAT_MODE_ONE:
|
||||
repeatToggleButton.setImageDrawable(repeatOneButtonDrawable);
|
||||
repeatToggleButton.setContentDescription(repeatOneButtonContentDescription);
|
||||
break;
|
||||
case ExoPlayer.REPEAT_MODE_ALL:
|
||||
case Player.REPEAT_MODE_ALL:
|
||||
repeatToggleButton.setImageDrawable(repeatAllButtonDrawable);
|
||||
repeatToggleButton.setContentDescription(repeatAllButtonContentDescription);
|
||||
break;
|
||||
|
|
@ -765,10 +768,10 @@ public class PlaybackControlView extends FrameLayout {
|
|||
|
||||
// Cancel any pending updates and schedule a new one if necessary.
|
||||
removeCallbacks(updateProgressAction);
|
||||
int playbackState = player == null ? ExoPlayer.STATE_IDLE : player.getPlaybackState();
|
||||
if (playbackState != ExoPlayer.STATE_IDLE && playbackState != ExoPlayer.STATE_ENDED) {
|
||||
int playbackState = player == null ? Player.STATE_IDLE : player.getPlaybackState();
|
||||
if (playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED) {
|
||||
long delayMs;
|
||||
if (player.getPlayWhenReady() && playbackState == ExoPlayer.STATE_READY) {
|
||||
if (player.getPlayWhenReady() && playbackState == Player.STATE_READY) {
|
||||
delayMs = 1000 - (position % 1000);
|
||||
if (delayMs < 200) {
|
||||
delayMs += 1000;
|
||||
|
|
@ -995,7 +998,7 @@ public class PlaybackControlView extends FrameLayout {
|
|||
return true;
|
||||
}
|
||||
|
||||
private final class ComponentListener implements ExoPlayer.EventListener, TimeBar.OnScrubListener,
|
||||
private final class ComponentListener implements Player.EventListener, TimeBar.OnScrubListener,
|
||||
OnClickListener {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in a new issue