Das CastPlayer ist eine Jetpack Media3-Implementierung von Player, die sowohl die lokale Wiedergabe als auch das Streaming auf ein für Google Cast optimiertes Remote-Gerät unterstützt. CastPlayer
Dadurch wird das Hinzufügen von Cast-Funktionen zu Ihrer App vereinfacht und es werden umfangreiche Funktionen für das nahtlose Umschalten zwischen lokaler und Remote-Wiedergabe bereitgestellt. In diesem Leitfaden erfahren Sie, wie Sie CastPlayer in Ihre Media-App einbinden.
Informationen zur Integration von Cast mit anderen Plattformen finden Sie im Cast SDK.
CastPlayer als Abhängigkeit hinzufügen
Wenn Sie CastPlayer verwenden möchten, fügen Sie die erforderlichen AndroidX Media3- und CastPlayer-Abhängigkeiten in die build.gradle-Datei Ihres App-Moduls ein.
Kotlin
implementation("androidx.media3:media3-exoplayer:1.9.0-alpha01") implementation("androidx.media3:media3-ui:1.9.0-alpha01") implementation("androidx.media3:media3-session:1.9.0-alpha01") implementation("androidx.media3:media3-cast:1.9.0-alpha01")
Groovy
implementation "androidx.media3:media3-exoplayer:1.9.0-alpha01" implementation "androidx.media3:media3-ui:1.9.0-alpha01" implementation "androidx.media3:media3-session:1.9.0-alpha01" implementation "androidx.media3:media3-cast:1.9.0-alpha01"
In den Versionshinweisen zu Jetpack Media finden Sie die aktuelle Alpha-Version, damit Sie CastPlayer in Ihre App einbinden können. Alle Module müssen dieselbe Version haben.
Weitere Informationen zu den verfügbaren Bibliotheksmodulen finden Sie auf der Seite Google Maven AndroidX Media3.
CastPlayer konfigurieren
Um den CastPlayer zu konfigurieren, müssen Sie die Datei AndroidManifest.xml mit einem Optionsanbieter aktualisieren.
Anbieter von Optionen
Für die CastPlayer ist ein Optionsanbieter erforderlich, um ihr Verhalten zu konfigurieren. Für eine einfache Einrichtung können Sie den Standardoptionsanbieter verwenden, indem Sie ihn Ihrer AndroidManifest.xml-Datei hinzufügen. Dabei werden Standardeinstellungen verwendet, einschließlich der Standardempfängeranwendung.
<application>
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
</application>
Wenn Sie die Konfiguration anpassen möchten, implementieren Sie eine eigene benutzerdefinierte OptionsProvider.
Weitere Informationen finden Sie im Leitfaden CastOptions.
Empfänger für die Medienübertragung hinzufügen
Wenn Sie Ihrem Manifest eine MediaTransferReceiver hinzufügen, kann die System-UI Medien umleiten, ohne die App-Aktivität zu öffnen. Ein Nutzer kann beispielsweise über die Medienbenachrichtigung das Gerät ändern, auf dem die Medien Ihrer App wiedergegeben werden.
<application>
<receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
</application>
CastPlayer erstellen
Für die Remote-Wiedergabe mit Cast sollte deine App die Wiedergabe auch dann verwalten können, wenn der Nutzer nicht mit einer Aktivität aus deiner App interagiert, z. B. über die Systembenachrichtigung für Medien. Aus diesem Grund sollten Sie Ihre ExoPlayer-Instanzen (für die lokale Wiedergabe) und CastPlayer-Instanzen (für die Remote-Wiedergabe) in einem Dienst wie MediaSessionService oder MediaLibraryService erstellen. Erstellen Sie zuerst Ihre ExoPlayer-Instanz und legen Sie dann beim Erstellen Ihrer CastPlayer-Instanz ExoPlayer als lokale Player-Instanz fest. Media3 kann dann Player-Übertragungen verarbeiten, wenn sich die Ausgaberoute von lokal zu remote oder von remote zu lokal ändert.
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(); }
UI-Elemente hinzufügen
Fügen Sie der Benutzeroberfläche Ihrer App ein MediaRouteButton hinzu, damit Nutzer ein Cast-Gerät auswählen können.
In diesem Abschnitt erfahren Sie, wie Sie die Schaltfläche hinzufügen und auf Ereignisse warten, um die Benutzeroberfläche zu aktualisieren, wenn die Wiedergabe zwischen lokalen und Remote-Geräten wechselt.
MediaRouteButton festlegen
Es gibt vier Möglichkeiten, den MediaRouteButton in die Benutzeroberfläche Ihrer Aktivität einzufügen, damit Nutzer damit interagieren können. Die Entscheidung hängt davon ab, wie die Benutzeroberfläche für die Spieleraktivitäten aussehen und funktionieren soll.
Schaltfläche für Composable-Media-Route zum Player hinzufügen
Sie können der Benutzeroberfläche Ihres Players die MediaRouteButton-Composable hinzufügen. Weitere Informationen finden Sie im Leitfaden zum Erstellen von E-Mails.
Kotlin
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.media3.cast.MediaRouteButton @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) { ... }
Schaltfläche für die Media-Route zur PlayerView hinzufügen
Sie können die MediaRouteButton direkt über die UI-Steuerelemente von PlayerView hinzufügen. Nachdem Sie MediaController als Player für Ihr PlayerView festgelegt haben, geben Sie ein MediaRouteButtonViewProvider an, um die Schaltfläche „Streamen“ auf dem Player anzuzeigen.
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()); }
Schaltfläche für die Media-Route zum App-Leistenmenü hinzufügen
Mit dieser Methode wird eine Schaltfläche für die Media-Route im App-Leistenmenü eingerichtet. Um diese Art von Schaltfläche anzuzeigen, sind Aktualisierungen sowohl der Manifestdatei als auch des Activity erforderlich.
<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) ... }
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); ... }
Schaltfläche für die Media-Route als Ansicht hinzufügen
Alternativ können Sie in Ihrer Datei „activity_layout.xml“ auch einen MediaRouteButton einrichten.
Verwenden Sie für die Einrichtung von MediaRouteButton das Media3 Cast-MediaRouteButtonFactory in Ihrem Activity-Code.
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) { ... MediaRouteButton button = findViewById(R.id.media_route_button); ListenableFuture<Void> setUpFuture = MediaRouteButtonFactory.setUpMediaRouteButton(context, button); }
Aktivitäts-Listener
Erstellen Sie in Ihrem Activity einen Player.Listener, um auf Änderungen des Wiedergabestandorts von Media zu reagieren. Wenn sich playbackType zwischen PLAYBACK_TYPE_LOCAL und PLAYBACK_TYPE_REMOTE ändert, können Sie die Benutzeroberfläche nach Bedarf anpassen. Um Speicherlecks zu vermeiden und die Listener-Aktivität auf die Zeit zu beschränken, in der Ihre App sichtbar ist, registrieren Sie den Listener in onStart und heben Sie die Registrierung in onStop auf:
Kotlin
import androidx.media3.common.DeviceInfo import androidx.media3.common.Player 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
import androidx.media3.common.DeviceInfo; import androidx.media3.common.Player; private 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); }
Weitere Informationen zum Abhören und Reagieren auf Wiedergabeereignisse finden Sie im Leitfaden zu Player-Ereignissen.