Migrate the cast demo app from PlayerView to StyledPlayerView

StyledPlayerControlView can't really be used on its own (like
PlayerControlView was used here), so we instead use the same
StyledPlayerView instance for both local and casted playback,
replacing the content with a cast icon while casting.

PiperOrigin-RevId: 410764338
This commit is contained in:
ibaker 2021-11-18 12:09:51 +00:00 committed by Ian Baker
parent a727220644
commit 21e659ef8e
4 changed files with 51 additions and 51 deletions

View File

@ -36,8 +36,7 @@ import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerControlView; import androidx.media3.ui.StyledPlayerView;
import androidx.media3.ui.PlayerView;
import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -53,8 +52,7 @@ import com.google.android.gms.dynamite.DynamiteModule;
public class MainActivity extends AppCompatActivity public class MainActivity extends AppCompatActivity
implements OnClickListener, PlayerManager.Listener { implements OnClickListener, PlayerManager.Listener {
private PlayerView localPlayerView; private StyledPlayerView playerView;
private PlayerControlView castControlView;
private PlayerManager playerManager; private PlayerManager playerManager;
private RecyclerView mediaQueueList; private RecyclerView mediaQueueList;
private MediaQueueListAdapter mediaQueueListAdapter; private MediaQueueListAdapter mediaQueueListAdapter;
@ -83,10 +81,8 @@ public class MainActivity extends AppCompatActivity
setContentView(R.layout.main_activity); setContentView(R.layout.main_activity);
localPlayerView = findViewById(R.id.local_player_view); playerView = findViewById(R.id.player_view);
localPlayerView.requestFocus(); playerView.requestFocus();
castControlView = findViewById(R.id.cast_control_view);
mediaQueueList = findViewById(R.id.sample_list); mediaQueueList = findViewById(R.id.sample_list);
ItemTouchHelper helper = new ItemTouchHelper(new RecyclerViewCallback()); ItemTouchHelper helper = new ItemTouchHelper(new RecyclerViewCallback());
@ -114,12 +110,7 @@ public class MainActivity extends AppCompatActivity
return; return;
} }
playerManager = playerManager =
new PlayerManager( new PlayerManager(/* listener= */ this, this, playerView, /* context= */ castContext);
/* listener= */ this,
localPlayerView,
castControlView,
/* context= */ this,
castContext);
mediaQueueList.setAdapter(mediaQueueListAdapter); mediaQueueList.setAdapter(mediaQueueListAdapter);
} }

View File

@ -17,7 +17,7 @@ package androidx.media3.demo.cast;
import android.content.Context; import android.content.Context;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.View; import androidx.core.content.res.ResourcesCompat;
import androidx.media3.cast.CastPlayer; import androidx.media3.cast.CastPlayer;
import androidx.media3.cast.SessionAvailabilityListener; import androidx.media3.cast.SessionAvailabilityListener;
import androidx.media3.common.C; import androidx.media3.common.C;
@ -28,8 +28,9 @@ import androidx.media3.common.Player.TimelineChangeReason;
import androidx.media3.common.Timeline; import androidx.media3.common.Timeline;
import androidx.media3.common.TracksInfo; import androidx.media3.common.TracksInfo;
import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerControlView;
import androidx.media3.ui.PlayerView; import androidx.media3.ui.PlayerView;
import androidx.media3.ui.StyledPlayerControlView;
import androidx.media3.ui.StyledPlayerView;
import com.google.android.gms.cast.framework.CastContext; import com.google.android.gms.cast.framework.CastContext;
import java.util.ArrayList; import java.util.ArrayList;
@ -50,8 +51,8 @@ import java.util.ArrayList;
void onUnsupportedTrack(int trackType); void onUnsupportedTrack(int trackType);
} }
private final PlayerView localPlayerView; private final Context context;
private final PlayerControlView castControlView; private final StyledPlayerView playerView;
private final Player localPlayer; private final Player localPlayer;
private final CastPlayer castPlayer; private final CastPlayer castPlayer;
private final ArrayList<MediaItem> mediaQueue; private final ArrayList<MediaItem> mediaQueue;
@ -64,32 +65,25 @@ import java.util.ArrayList;
/** /**
* Creates a new manager for {@link ExoPlayer} and {@link CastPlayer}. * Creates a new manager for {@link ExoPlayer} and {@link CastPlayer}.
* *
* @param listener A {@link Listener} for queue position changes.
* @param localPlayerView The {@link PlayerView} for local playback.
* @param castControlView The {@link PlayerControlView} to control remote playback.
* @param context A {@link Context}. * @param context A {@link Context}.
* @param listener A {@link Listener} for queue position changes.
* @param playerView The {@link PlayerView} for playback.
* @param castContext The {@link CastContext}. * @param castContext The {@link CastContext}.
*/ */
public PlayerManager( public PlayerManager(
Listener listener, Context context, Listener listener, StyledPlayerView playerView, CastContext castContext) {
PlayerView localPlayerView, this.context = context;
PlayerControlView castControlView,
Context context,
CastContext castContext) {
this.listener = listener; this.listener = listener;
this.localPlayerView = localPlayerView; this.playerView = playerView;
this.castControlView = castControlView;
mediaQueue = new ArrayList<>(); mediaQueue = new ArrayList<>();
currentItemIndex = C.INDEX_UNSET; currentItemIndex = C.INDEX_UNSET;
localPlayer = new ExoPlayer.Builder(context).build(); localPlayer = new ExoPlayer.Builder(context).build();
localPlayer.addListener(this); localPlayer.addListener(this);
localPlayerView.setPlayer(localPlayer);
castPlayer = new CastPlayer(castContext); castPlayer = new CastPlayer(castContext);
castPlayer.addListener(this); castPlayer.addListener(this);
castPlayer.setSessionAvailabilityListener(this); castPlayer.setSessionAvailabilityListener(this);
castControlView.setPlayer(castPlayer);
setCurrentPlayer(castPlayer.isCastSessionAvailable() ? castPlayer : localPlayer); setCurrentPlayer(castPlayer.isCastSessionAvailable() ? castPlayer : localPlayer);
} }
@ -192,11 +186,7 @@ import java.util.ArrayList;
* @return Whether the event was handled by the target view. * @return Whether the event was handled by the target view.
*/ */
public boolean dispatchKeyEvent(KeyEvent event) { public boolean dispatchKeyEvent(KeyEvent event) {
if (currentPlayer == localPlayer) { return playerView.dispatchKeyEvent(event);
return localPlayerView.dispatchKeyEvent(event);
} else /* currentPlayer == castPlayer */ {
return castControlView.dispatchKeyEvent(event);
}
} }
/** Releases the manager and the players that it holds. */ /** Releases the manager and the players that it holds. */
@ -205,7 +195,7 @@ import java.util.ArrayList;
mediaQueue.clear(); mediaQueue.clear();
castPlayer.setSessionAvailabilityListener(null); castPlayer.setSessionAvailabilityListener(null);
castPlayer.release(); castPlayer.release();
localPlayerView.setPlayer(null); playerView.setPlayer(null);
localPlayer.release(); localPlayer.release();
} }
@ -270,13 +260,19 @@ import java.util.ArrayList;
return; return;
} }
// View management. playerView.setPlayer(currentPlayer);
if (currentPlayer == localPlayer) { playerView.setControllerHideOnTouch(currentPlayer == localPlayer);
localPlayerView.setVisibility(View.VISIBLE); if (currentPlayer == castPlayer) {
castControlView.hide(); playerView.setControllerShowTimeoutMs(0);
} else /* currentPlayer == castPlayer */ { playerView.showController();
localPlayerView.setVisibility(View.GONE); playerView.setDefaultArtwork(
castControlView.show(); ResourcesCompat.getDrawable(
context.getResources(),
R.drawable.ic_baseline_cast_connected_400,
/* theme= */ null));
} else { // currentPlayer == localPlayer
playerView.setControllerShowTimeoutMs(StyledPlayerControlView.DEFAULT_SHOW_TIMEOUT_MS);
playerView.setDefaultArtwork(null);
} }
// Player state management. // Player state management.

View File

@ -0,0 +1,20 @@
<!--
~ Copyright 2021 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
~
~ https://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.
-->
<vector android:height="400dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="400dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M1,18v3h3c0,-1.66 -1.34,-3 -3,-3zM1,14v2c2.76,0 5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM1,10v2c4.97,0 9,4.03 9,9h2c0,-6.08 -4.93,-11 -11,-11zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>

View File

@ -20,7 +20,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:keepScreenOn="true"> android:keepScreenOn="true">
<androidx.media3.ui.PlayerView android:id="@+id/local_player_view" <androidx.media3.ui.StyledPlayerView android:id="@+id/player_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
@ -50,11 +50,4 @@
</RelativeLayout> </RelativeLayout>
<androidx.media3.ui.PlayerControlView android:id="@+id/cast_control_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:repeat_toggle_modes="all|one"
app:show_timeout="-1"/>
</LinearLayout> </LinearLayout>