Some no-op LeanbackPlayerAdapter cleanup
- Have a single inner class for all listeners. This is inline with what we do elsewhere in the library. - Avoid repeated getCallback() calls within methods. - Seek to default position from ended state, rather than 0. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=165603927
This commit is contained in:
parent
e3f305b5c0
commit
106d88df41
@ -26,7 +26,6 @@ import android.view.Surface;
|
|||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
|
||||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
@ -37,7 +36,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
|||||||
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
import com.google.android.exoplayer2.util.ErrorMessageProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Leanback {@link PlayerAdapter} implementation for {@link SimpleExoPlayer}.
|
* Leanback {@code PlayerAdapter} implementation for {@link SimpleExoPlayer}.
|
||||||
*/
|
*/
|
||||||
public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
||||||
|
|
||||||
@ -48,58 +47,49 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
private final Context context;
|
private final Context context;
|
||||||
private final SimpleExoPlayer player;
|
private final SimpleExoPlayer player;
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
private final Runnable updatePlayerRunnable = new Runnable() {
|
private final ComponentListener componentListener;
|
||||||
@Override
|
private final Runnable updatePlayerRunnable;
|
||||||
public void run() {
|
|
||||||
getCallback().onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
|
||||||
getCallback().onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
|
||||||
handler.postDelayed(this, updatePeriod);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private ErrorMessageProvider<? super ExoPlaybackException> errorMessageProvider;
|
||||||
private SurfaceHolderGlueHost surfaceHolderGlueHost;
|
private SurfaceHolderGlueHost surfaceHolderGlueHost;
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
private boolean hasSurface;
|
private boolean hasSurface;
|
||||||
private boolean isBuffering;
|
private boolean isBuffering;
|
||||||
private ErrorMessageProvider<? super ExoPlaybackException> errorMessageProvider;
|
|
||||||
private final int updatePeriod;
|
|
||||||
private final ExoPlayerEventListenerImpl exoPlayerListener = new ExoPlayerEventListenerImpl();
|
|
||||||
private final SimpleExoPlayer.VideoListener videoListener = new SimpleExoPlayer.VideoListener() {
|
|
||||||
@Override
|
|
||||||
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
|
|
||||||
float pixelWidthHeightRatio) {
|
|
||||||
getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRenderedFirstFrame() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Builds an instance. Note that the {@code PlayerAdapter} does not manage the lifecycle of the
|
||||||
* Users are responsible for managing {@link SimpleExoPlayer} lifecycle. You must
|
* {@link SimpleExoPlayer} instance. The caller remains responsible for releasing the player when
|
||||||
* stop/release the player once you're done playing the media.
|
* it's no longer required.
|
||||||
*
|
*
|
||||||
* @param context The current context (activity).
|
* @param context The current context (activity).
|
||||||
* @param player Instance of your exoplayer that needs to be configured.
|
* @param player Instance of your exoplayer that needs to be configured.
|
||||||
|
* @param updatePeriodMs The delay between player control updates, in milliseconds.
|
||||||
*/
|
*/
|
||||||
public LeanbackPlayerAdapter(Context context, SimpleExoPlayer player, int updatePeriod) {
|
public LeanbackPlayerAdapter(Context context, SimpleExoPlayer player, final int updatePeriodMs) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.handler = new Handler();
|
handler = new Handler();
|
||||||
this.updatePeriod = updatePeriod;
|
componentListener = new ComponentListener();
|
||||||
|
updatePlayerRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Callback callback = getCallback();
|
||||||
|
callback.onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
|
callback.onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
|
handler.postDelayed(this, updatePeriodMs);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToHost(PlaybackGlueHost host) {
|
public void onAttachedToHost(PlaybackGlueHost host) {
|
||||||
if (host instanceof SurfaceHolderGlueHost) {
|
if (host instanceof SurfaceHolderGlueHost) {
|
||||||
surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host);
|
surfaceHolderGlueHost = ((SurfaceHolderGlueHost) host);
|
||||||
surfaceHolderGlueHost.setSurfaceHolderCallback(new VideoPlayerSurfaceHolderCallback());
|
surfaceHolderGlueHost.setSurfaceHolderCallback(componentListener);
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
player.addListener(exoPlayerListener);
|
player.addListener(componentListener);
|
||||||
player.addVideoListener(videoListener);
|
player.addVideoListener(componentListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyListeners() {
|
private void notifyListeners() {
|
||||||
@ -110,15 +100,14 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
boolean hasEnded = playbackState == Player.STATE_ENDED;
|
boolean hasEnded = playbackState == Player.STATE_ENDED;
|
||||||
|
|
||||||
initialized = isInitialized;
|
initialized = isInitialized;
|
||||||
|
Callback callback = getCallback();
|
||||||
if (oldIsPrepared != isPrepared()) {
|
if (oldIsPrepared != isPrepared()) {
|
||||||
getCallback().onPreparedStateChanged(this);
|
callback.onPreparedStateChanged(this);
|
||||||
}
|
}
|
||||||
|
callback.onPlayStateChanged(this);
|
||||||
getCallback().onPlayStateChanged(this);
|
callback.onBufferingStateChanged(this, isBuffering || !initialized);
|
||||||
getCallback().onBufferingStateChanged(this, isBuffering || !initialized);
|
|
||||||
|
|
||||||
if (hasEnded) {
|
if (hasEnded) {
|
||||||
getCallback().onPlayCompleted(this);
|
callback.onPlayCompleted(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +123,8 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromHost() {
|
public void onDetachedFromHost() {
|
||||||
player.removeListener(exoPlayerListener);
|
player.removeListener(componentListener);
|
||||||
player.removeVideoListener(videoListener);
|
player.removeVideoListener(componentListener);
|
||||||
if (surfaceHolderGlueHost != null) {
|
if (surfaceHolderGlueHost != null) {
|
||||||
surfaceHolderGlueHost.setSurfaceHolderCallback(null);
|
surfaceHolderGlueHost.setSurfaceHolderCallback(null);
|
||||||
surfaceHolderGlueHost = null;
|
surfaceHolderGlueHost = null;
|
||||||
@ -151,10 +140,9 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void setProgressUpdatingEnabled(final boolean enabled) {
|
public void setProgressUpdatingEnabled(final boolean enabled) {
|
||||||
handler.removeCallbacks(updatePlayerRunnable);
|
handler.removeCallbacks(updatePlayerRunnable);
|
||||||
if (!enabled) {
|
if (enabled) {
|
||||||
return;
|
handler.post(updatePlayerRunnable);
|
||||||
}
|
}
|
||||||
handler.postDelayed(updatePlayerRunnable, updatePeriod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,8 +152,8 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDuration() {
|
public long getDuration() {
|
||||||
long duration = player.getDuration();
|
long durationMs = player.getDuration();
|
||||||
return duration != C.TIME_UNSET ? duration : -1;
|
return durationMs != C.TIME_UNSET ? durationMs : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -176,7 +164,7 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void play() {
|
public void play() {
|
||||||
if (player.getPlaybackState() == Player.STATE_ENDED) {
|
if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||||
seekTo(0);
|
player.seekToDefaultPosition();
|
||||||
}
|
}
|
||||||
player.setPlayWhenReady(true);
|
player.setPlayWhenReady(true);
|
||||||
getCallback().onPlayStateChanged(this);
|
getCallback().onPlayStateChanged(this);
|
||||||
@ -198,10 +186,6 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
return player.getBufferedPosition();
|
return player.getBufferedPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return True if ExoPlayer is ready and got a SurfaceHolder if
|
|
||||||
* {@link PlaybackGlueHost} provides SurfaceHolder.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrepared() {
|
public boolean isPrepared() {
|
||||||
return initialized && (surfaceHolderGlueHost == null || hasSurface);
|
return initialized && (surfaceHolderGlueHost == null || hasSurface);
|
||||||
@ -213,10 +197,11 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
getCallback().onPreparedStateChanged(this);
|
getCallback().onPreparedStateChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private final class ComponentListener implements Player.EventListener,
|
||||||
* Implements {@link SurfaceHolder.Callback} that can then be set on the {@link PlaybackGlueHost}.
|
SimpleExoPlayer.VideoListener, SurfaceHolder.Callback {
|
||||||
*/
|
|
||||||
private final class VideoPlayerSurfaceHolderCallback implements SurfaceHolder.Callback {
|
// SurfaceHolder.Callback implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||||
setVideoSurface(surfaceHolder.getSurface());
|
setVideoSurface(surfaceHolder.getSurface());
|
||||||
@ -224,67 +209,82 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||||
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
||||||
setVideoSurface(null);
|
setVideoSurface(null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private final class ExoPlayerEventListenerImpl implements ExoPlayer.EventListener {
|
// Player.EventListener implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||||
LeanbackPlayerAdapter.this.notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerError(ExoPlaybackException exception) {
|
public void onPlayerError(ExoPlaybackException exception) {
|
||||||
|
Callback callback = getCallback();
|
||||||
if (errorMessageProvider != null) {
|
if (errorMessageProvider != null) {
|
||||||
Pair<Integer, String> message = errorMessageProvider.getErrorMessage(exception);
|
Pair<Integer, String> errorMessage = errorMessageProvider.getErrorMessage(exception);
|
||||||
if (message != null) {
|
callback.onError(LeanbackPlayerAdapter.this, errorMessage.first, errorMessage.second);
|
||||||
getCallback().onError(LeanbackPlayerAdapter.this,
|
} else {
|
||||||
message.first,
|
callback.onError(LeanbackPlayerAdapter.this, exception.type, context.getString(
|
||||||
message.second);
|
R.string.lb_media_player_error, exception.type, exception.rendererIndex));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getCallback().onError(LeanbackPlayerAdapter.this,
|
|
||||||
exception.type,
|
|
||||||
context.getString(R.string.lb_media_player_error,
|
|
||||||
exception.type,
|
|
||||||
exception.rendererIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingChanged(boolean isLoading) {
|
public void onLoadingChanged(boolean isLoading) {
|
||||||
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||||
getCallback().onDurationChanged(LeanbackPlayerAdapter.this);
|
Callback callback = getCallback();
|
||||||
getCallback().onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
callback.onDurationChanged(LeanbackPlayerAdapter.this);
|
||||||
getCallback().onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
callback.onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
|
callback.onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
||||||
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPositionDiscontinuity() {
|
public void onPositionDiscontinuity() {
|
||||||
getCallback().onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
Callback callback = getCallback();
|
||||||
getCallback().onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
callback.onCurrentPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
|
callback.onBufferedPositionChanged(LeanbackPlayerAdapter.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaybackParametersChanged(PlaybackParameters params) {
|
public void onPlaybackParametersChanged(PlaybackParameters params) {
|
||||||
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRepeatModeChanged(int repeatMode) {
|
public void onRepeatModeChanged(int repeatMode) {
|
||||||
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SimpleExoplayerView.Callback implementation.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
|
||||||
|
float pixelWidthHeightRatio) {
|
||||||
|
getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRenderedFirstFrame() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user