Commit fc271049 by aquilescanta Committed by Andrew Lewis

Handle player errors more gracefully in the Cast demo app

PiperOrigin-RevId: 233090773
parent 3d822bd2
...@@ -33,6 +33,7 @@ import android.view.ViewGroup; ...@@ -33,6 +33,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ext.cast.MediaItem; import com.google.android.exoplayer2.ext.cast.MediaItem;
...@@ -48,7 +49,7 @@ import java.util.Collections; ...@@ -48,7 +49,7 @@ import java.util.Collections;
* Cast extension. * Cast extension.
*/ */
public class MainActivity extends AppCompatActivity public class MainActivity extends AppCompatActivity
implements OnClickListener, PlayerManager.QueueChangesListener { implements OnClickListener, PlayerManager.Listener {
private final MediaItem.Builder mediaItemBuilder; private final MediaItem.Builder mediaItemBuilder;
...@@ -118,7 +119,7 @@ public class MainActivity extends AppCompatActivity ...@@ -118,7 +119,7 @@ public class MainActivity extends AppCompatActivity
} }
playerManager = playerManager =
new PlayerManager( new PlayerManager(
/* queueChangesListener= */ this, /* listener= */ this,
localPlayerView, localPlayerView,
castControlView, castControlView,
/* context= */ this, /* context= */ this,
...@@ -154,7 +155,7 @@ public class MainActivity extends AppCompatActivity ...@@ -154,7 +155,7 @@ public class MainActivity extends AppCompatActivity
.show(); .show();
} }
// PlayerManager.QueueChangesListener implementation. // PlayerManager.Listener implementation.
@Override @Override
public void onQueuePositionChanged(int previousIndex, int newIndex) { public void onQueuePositionChanged(int previousIndex, int newIndex) {
...@@ -171,6 +172,11 @@ public class MainActivity extends AppCompatActivity ...@@ -171,6 +172,11 @@ public class MainActivity extends AppCompatActivity
mediaQueueListAdapter.notifyDataSetChanged(); mediaQueueListAdapter.notifyDataSetChanged();
} }
@Override
public void onPlayerError() {
Toast.makeText(getApplicationContext(), R.string.player_error_msg, Toast.LENGTH_LONG).show();
}
// Internal methods. // Internal methods.
private View buildSampleListView() { private View buildSampleListView() {
......
...@@ -22,6 +22,7 @@ import android.view.KeyEvent; ...@@ -22,6 +22,7 @@ import android.view.KeyEvent;
import android.view.View; import android.view.View;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Player.DiscontinuityReason; import com.google.android.exoplayer2.Player.DiscontinuityReason;
...@@ -45,22 +46,27 @@ import com.google.android.exoplayer2.ui.PlayerControlView; ...@@ -45,22 +46,27 @@ import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView; import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.gms.cast.framework.CastContext; import com.google.android.gms.cast.framework.CastContext;
import java.util.ArrayList; import java.util.ArrayList;
/** Manages players and an internal media queue for the Cast demo app. */ /** Manages players and an internal media queue for the Cast demo app. */
/* package */ class PlayerManager implements EventListener, SessionAvailabilityListener { /* package */ class PlayerManager implements EventListener, SessionAvailabilityListener {
/** Listener for changes in the media queue. */ /** Listener for events. */
public interface QueueChangesListener { public interface Listener {
/** Called when the currently played item of the media queue changes. */ /** Called when the currently played item of the media queue changes. */
void onQueuePositionChanged(int previousIndex, int newIndex); void onQueuePositionChanged(int previousIndex, int newIndex);
/** Called when the media queue changes due to modifications not caused by this manager. */ /** Called when the media queue changes due to modifications not caused by this manager. */
void onQueueContentsExternallyChanged(); void onQueueContentsExternallyChanged();
/** Called when an error occurs in the current player. */
void onPlayerError();
} }
private static final String TAG = "PlayerManager";
private static final String USER_AGENT = "ExoCastDemoPlayer"; private static final String USER_AGENT = "ExoCastDemoPlayer";
private static final DefaultHttpDataSourceFactory DATA_SOURCE_FACTORY = private static final DefaultHttpDataSourceFactory DATA_SOURCE_FACTORY =
new DefaultHttpDataSourceFactory(USER_AGENT); new DefaultHttpDataSourceFactory(USER_AGENT);
...@@ -70,7 +76,7 @@ import java.util.ArrayList; ...@@ -70,7 +76,7 @@ import java.util.ArrayList;
private final SimpleExoPlayer exoPlayer; private final SimpleExoPlayer exoPlayer;
private final ExoCastPlayer exoCastPlayer; private final ExoCastPlayer exoCastPlayer;
private final ArrayList<MediaItem> mediaQueue; private final ArrayList<MediaItem> mediaQueue;
private final QueueChangesListener queueChangesListener; private final Listener listener;
private final ConcatenatingMediaSource concatenatingMediaSource; private final ConcatenatingMediaSource concatenatingMediaSource;
private int currentItemIndex; private int currentItemIndex;
...@@ -79,19 +85,19 @@ import java.util.ArrayList; ...@@ -79,19 +85,19 @@ import java.util.ArrayList;
/** /**
* Creates a new manager for {@link SimpleExoPlayer} and {@link ExoCastPlayer}. * Creates a new manager for {@link SimpleExoPlayer} and {@link ExoCastPlayer}.
* *
* @param queueChangesListener A {@link QueueChangesListener}. * @param listener A {@link Listener}.
* @param localPlayerView The {@link PlayerView} for local playback. * @param localPlayerView The {@link PlayerView} for local playback.
* @param castControlView The {@link PlayerControlView} to control remote playback. * @param castControlView The {@link PlayerControlView} to control remote playback.
* @param context A {@link Context}. * @param context A {@link Context}.
* @param castContext The {@link CastContext}. * @param castContext The {@link CastContext}.
*/ */
public PlayerManager( public PlayerManager(
QueueChangesListener queueChangesListener, Listener listener,
PlayerView localPlayerView, PlayerView localPlayerView,
PlayerControlView castControlView, PlayerControlView castControlView,
Context context, Context context,
CastContext castContext) { CastContext castContext) {
this.queueChangesListener = queueChangesListener; this.listener = listener;
this.localPlayerView = localPlayerView; this.localPlayerView = localPlayerView;
this.castControlView = castControlView; this.castControlView = castControlView;
mediaQueue = new ArrayList<>(); mediaQueue = new ArrayList<>();
...@@ -105,7 +111,9 @@ import java.util.ArrayList; ...@@ -105,7 +111,9 @@ import java.util.ArrayList;
localPlayerView.setPlayer(exoPlayer); localPlayerView.setPlayer(exoPlayer);
exoCastPlayer = exoCastPlayer =
new ExoCastPlayer(listener -> new DefaultCastSessionManager(castContext, listener)); new ExoCastPlayer(
sessionManagerListener ->
new DefaultCastSessionManager(castContext, sessionManagerListener));
exoCastPlayer.addListener(this); exoCastPlayer.addListener(this);
exoCastPlayer.setSessionAvailabilityListener(this); exoCastPlayer.setSessionAvailabilityListener(this);
castControlView.setPlayer(exoCastPlayer); castControlView.setPlayer(exoCastPlayer);
...@@ -238,6 +246,12 @@ import java.util.ArrayList; ...@@ -238,6 +246,12 @@ import java.util.ArrayList;
updateCurrentItemIndex(); updateCurrentItemIndex();
} }
@Override
public void onPlayerError(ExoPlaybackException error) {
Log.e(TAG, "The player encountered an error.", error);
listener.onPlayerError();
}
// CastPlayer.SessionAvailabilityListener implementation. // CastPlayer.SessionAvailabilityListener implementation.
@Override @Override
...@@ -269,7 +283,7 @@ import java.util.ArrayList; ...@@ -269,7 +283,7 @@ import java.util.ArrayList;
mediaQueue.add(item); mediaQueue.add(item);
concatenatingMediaSource.addMediaSource(buildMediaSource(item)); concatenatingMediaSource.addMediaSource(buildMediaSource(item));
} }
queueChangesListener.onQueueContentsExternallyChanged(); listener.onQueueContentsExternallyChanged();
} }
private void updateCurrentItemIndex() { private void updateCurrentItemIndex() {
...@@ -359,6 +373,13 @@ import java.util.ArrayList; ...@@ -359,6 +373,13 @@ import java.util.ArrayList;
private void setCurrentItem(int itemIndex, long positionMs, boolean playWhenReady) { private void setCurrentItem(int itemIndex, long positionMs, boolean playWhenReady) {
maybeSetCurrentItemAndNotify(itemIndex); maybeSetCurrentItemAndNotify(itemIndex);
currentPlayer.seekTo(itemIndex, positionMs); currentPlayer.seekTo(itemIndex, positionMs);
if (currentPlayer.getPlaybackState() == Player.STATE_IDLE) {
if (currentPlayer == exoCastPlayer) {
exoCastPlayer.prepare();
} else {
exoPlayer.prepare(concatenatingMediaSource);
}
}
currentPlayer.setPlayWhenReady(playWhenReady); currentPlayer.setPlayWhenReady(playWhenReady);
} }
...@@ -366,7 +387,7 @@ import java.util.ArrayList; ...@@ -366,7 +387,7 @@ import java.util.ArrayList;
if (this.currentItemIndex != currentItemIndex) { if (this.currentItemIndex != currentItemIndex) {
int oldIndex = this.currentItemIndex; int oldIndex = this.currentItemIndex;
this.currentItemIndex = currentItemIndex; this.currentItemIndex = currentItemIndex;
queueChangesListener.onQueuePositionChanged(oldIndex, currentItemIndex); listener.onQueuePositionChanged(oldIndex, currentItemIndex);
} }
} }
......
...@@ -24,4 +24,6 @@ ...@@ -24,4 +24,6 @@
<string name="cast_context_error">Failed to get Cast context. Try updating Google Play Services and restart the app.</string> <string name="cast_context_error">Failed to get Cast context. Try updating Google Play Services and restart the app.</string>
<string name="player_error_msg">Player error encountered. Select a queue item to reprepare. Check the logcat and receiver app\'s console for more info.</string>
</resources> </resources>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment