CastPlayer to implementacja odtwarzacza Jetpack Media3, która obsługuje zarówno odtwarzanie lokalne, jak i przesyłanie na zdalne urządzenie obsługujące Cast. CastPlayer
ułatwia dodawanie do aplikacji funkcji przesyłania i zapewnia bogate funkcje, które umożliwiają
płynne przełączanie się między odtwarzaniem lokalnym i zdalnym. Z tego przewodnika dowiesz się, jak zintegrować CastPlayer z aplikacją multimedialną.
Aby zintegrować Cast z innymi platformami, zapoznaj się z pakietem Cast SDK.
Kup urządzenie obsługujące Cast
Aby przetestować CastPlayer, musisz mieć urządzenie obsługujące Cast. Możesz wybrać urządzenia z Androidem TV, Chromecasta, inteligentne głośniki i inteligentne ekrany. Sprawdź, czy urządzenie jest skonfigurowane i połączone z tą samą siecią Wi-Fi co urządzenie mobilne, na którym prowadzisz testy.
Dodawanie zależności kompilacji
Aby zacząć korzystać z CastPlayer, dodaj zależności AndroidX Media3 i CastPlayer do pliku build.gradle modułu aplikacji.
Kotlin
implementation("androidx.media3:media3-exoplayer:1.9.2")
implementation("androidx.media3:media3-ui:1.9.2")
implementation("androidx.media3:media3-session:1.9.2")
implementation("androidx.media3:media3-cast:1.9.2")
Groovy
implementation "androidx.media3:media3-exoplayer:1.9.2"
implementation "androidx.media3:media3-ui:1.9.2"
implementation "androidx.media3:media3-session:1.9.2"
implementation "androidx.media3:media3-cast:1.9.2"
Konfigurowanie CastPlayer
Aby skonfigurować CastPlayer, zaktualizuj plik AndroidManifest.xml, dodając dostawcę opcji.
Dostawca opcji
Element CastPlayer wymaga skonfigurowania jego działania przez dostawcę opcji. W przypadku konfiguracji podstawowej możesz użyć DefaultCastOptionsProvider, dodając go do pliku AndroidManifest.xml. Spowoduje to użycie ustawień domyślnych, w tym domyślnej aplikacji odbiornika.
<application>
...
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
...
</application>
Aby dostosować konfigurację, zaimplementuj własny element OptionsProvider. Więcej informacji znajdziesz w przewodniku CastOptions.
Dodawanie odbiorcy do przesyłania multimediów
Dodanie elementu MediaTransferReceiver do pliku manifestu umożliwia interfejsowi systemu wykrywanie w sieci urządzeń obsługujących Cast i przekierowywanie multimediów bez otwierania aktywności aplikacji. Użytkownik może na przykład zmienić urządzenie, na którym odtwarzane są multimedia z Twojej aplikacji, za pomocą powiadomienia o multimediach.
<application>
...
<receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
...
</application>
Tworzenie odtwarzacza CastPlayer
W przypadku odtwarzania zdalnego za pomocą Cast aplikacja powinna zarządzać odtwarzaniem nawet wtedy, gdy użytkownik nie wchodzi w interakcję z aktywnością w aplikacji, np. za pomocą systemowego powiadomienia o multimediach. Z tego powodu instancje ExoPlayer (do odtwarzania lokalnego) i CastPlayer (do odtwarzania zdalnego) należy tworzyć w usłudze, np. MediaSessionService lub MediaLibraryService.
Najpierw utwórz instancję ExoPlayer, a potem podczas tworzenia instancji CastPlayer ustaw ExoPlayer jako instancję lokalnego odtwarzacza. Możesz wtedy przełączać odtwarzanie multimediów między urządzeniem mobilnym a urządzeniem obsługującym Cast z poziomu powiadomienia o multimediach lub powiadomienia na ekranie blokady. Media3 korzysta z funkcji OutputSwitcher, aby obsługiwać przenoszenie odtwarzacza, gdy trasa wyjściowa zmienia się z lokalnej na zdalną lub ze zdalnej na lokalną.
Kotlin
override fun onCreate() { super.onCreate() val exoPlayer = ExoPlayer.Builder(context).build() val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build() mediaSession = MediaSession.Builder(context, castPlayer).build() }
Java
@Override public void onCreate() { super.onCreate(); ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build(); CastPlayer castPlayer = new CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build(); mediaSession = new MediaSession.Builder(/* context= */ context, /* player= */ castPlayer).build(); }
Dodawanie elementów interfejsu
Dodaj MediaRouteButton do interfejsu aplikacji. Kliknięcie MediaRouteButton
otwiera okno z listą dostępnych urządzeń obsługujących Cast w sieci. Gdy użytkownik wybierze urządzenie, odtwarzanie multimediów zostanie przeniesione z telefonu na wybrane urządzenie odbiorcze. W tej sekcji dowiesz się, jak dodać przycisk i nasłuchiwać zdarzeń, aby aktualizować interfejs, gdy odtwarzanie przełącza się między urządzeniami lokalnymi i zdalnymi.
Ustawianie elementu MediaRouteButton
Istnieją 4 sposoby dodania elementu MediaRouteButton do interfejsu aktywności. Najlepszy wybór zależy od projektu i wymagań aplikacji.
- Compose UI: dodaj funkcję kompozycyjną przycisku.
- Interfejs wyświetleń:
- Dodaj przycisk do menu paska aplikacji.
- Dodaj przycisk w tagu
PlayerView. - Dodaj przycisk jako standardowy
View.
Dodawanie komponentu MediaRouteButton do odtwarzacza
Możesz dodać komponent MediaRouteButton do interfejsu odtwarzacza. Więcej informacji znajdziesz w przewodniku Compose.
@Composable fun PlayerComposeView(player: Player, modifier: Modifier = Modifier) { var controlsVisible by remember { mutableStateOf(false) } Box( modifier = modifier.clickable { controlsVisible = true }, contentAlignment = Alignment.Center, ) { PlayerSurface(player = player, modifier = modifier) AnimatedVisibility(visible = controlsVisible, enter = fadeIn(), exit = fadeOut()) { Box(modifier = Modifier.fillMaxSize()) { MediaRouteButton(modifier = Modifier.align(Alignment.TopEnd)) PrimaryControls(player = player, modifier = Modifier.align(Alignment.Center)) } } } } @Composable fun PrimaryControls(player: Player, modifier: Modifier = Modifier) { // ... }
Dodaj MediaRouteButton do PlayerView
Możesz dodać MediaRouteButton bezpośrednio w elementach interfejsu PlayerView. Po ustawieniu MediaController jako odtwarzacza dla elementu PlayerView podaj element MediaRouteButtonViewProvider, aby wyświetlić przycisk przesyłania na odtwarzaczu.
Kotlin
override fun onStart() { super.onStart() playerView.player = mediaController playerView.setMediaRouteButtonViewProvider(MediaRouteButtonViewProvider()) }
Java
@Override public void onStart() { super.onStart(); playerView.setPlayer(mediaController); playerView.setMediaRouteButtonViewProvider(new MediaRouteButtonViewProvider()); }
Dodawanie ikony MediaRouteButton do menu paska aplikacji
Aby skonfigurować MediaRouteButton w menu paska aplikacji, utwórz menu XML i zastąp onCreateOptionsMenu w Activity.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:showAsAction="always"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"/>
</menu>
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { // ... menuInflater.inflate(R.menu.sample_media_route_button_menu, menu) val menuItemFuture: ListenableFuture<MenuItem> = MediaRouteButtonFactory.setUpMediaRouteButton(context, menu, R.id.media_route_menu_item) Futures.addCallback( menuItemFuture, object : FutureCallback<MenuItem> { override fun onSuccess(menuItem: MenuItem?) { // Do something with the menu item. } override fun onFailure(t: Throwable) { // Handle the failure. } }, executor, ) // ... return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { // ... getMenuInflater().inflate(R.menu.sample_media_route_button_menu, menu); ListenableFuture<MenuItem> menuItemFuture = MediaRouteButtonFactory.setUpMediaRouteButton(context, menu, R.id.media_route_menu_item); Futures.addCallback( menuItemFuture, new FutureCallback<MenuItem>() { @Override public void onSuccess(MenuItem menuItem) { // Do something with the menu item. } @Override public void onFailure(Throwable t) { // Handle the failure. } }, executor); // ... return true; }
Dodaj MediaRouteButton jako widok
Możesz skonfigurować MediaRouteButton w pliku układu aktywności layout.xml.
<androidx.mediarouter.app.MediaRouteButton
android:id="@+id/media_route_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:mediaRouteButtonTint="@android:color/white" />
Aby dokończyć konfigurację MediaRouteButton, użyj w kodzie Activity interfejsu Media3 CastMediaRouteButtonFactory.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<MediaRouteButton>(R.id.media_route_button)?.also { val unused = MediaRouteButtonFactory.setUpMediaRouteButton(context, it) } }
Java
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... MediaRouteButton button = findViewById(R.id.media_route_button); ListenableFuture<Void> setUpFuture = MediaRouteButtonFactory.setUpMediaRouteButton(context, button); }
Detektor aktywności
Utwórz Player.Listener w Activity, aby nasłuchiwać zmian lokalizacji odtwarzania multimediów. Gdy playbackType zmieni się z PLAYBACK_TYPE_LOCAL na PLAYBACK_TYPE_REMOTE, możesz dostosować interfejs do swoich potrzeb. Aby zapobiec wyciekom pamięci i ograniczyć aktywność odbiornika tylko do momentu, gdy aplikacja jest widoczna, zarejestruj odbiornik w funkcji onStart i wyrejestruj go w funkcji onStop:
Kotlin
private val playerListener: Player.Listener = object : Player.Listener { override fun onDeviceInfoChanged(deviceInfo: DeviceInfo) { if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_LOCAL) { // Add UI changes for local playback. } else if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_REMOTE) { // Add UI changes for remote playback. } } } override fun onStart() { super.onStart() mediaController.addListener(playerListener) } override fun onStop() { super.onStop() mediaController.removeListener(playerListener) }
Java
private final Player.Listener playerListener = new Player.Listener() { @Override public void onDeviceInfoChanged(DeviceInfo deviceInfo) { if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_LOCAL) { // Add UI changes for local playback. } else if (deviceInfo.playbackType == DeviceInfo.PLAYBACK_TYPE_REMOTE) { // Add UI changes for remote playback. } } }; @Override protected void onStart() { super.onStart(); mediaController.addListener(playerListener); } @Override protected void onStop() { super.onStop(); mediaController.removeListener(playerListener); }
Więcej informacji o nasłuchiwaniu zdarzeń odtwarzania i reagowaniu na nie znajdziesz w przewodniku Zdarzenia odtwarzacza.