Mulai menggunakan CastPlayer

CastPlayer adalah implementasi Player Jetpack Media3 yang mendukung pemutaran lokal dan transmisi ke perangkat jarak jauh yang kompatibel untuk Cast. CastPlayer menyederhanakan penambahan fungsi transmisi ke aplikasi Anda dan menyediakan fitur lengkap untuk beralih dengan lancar antara pemutaran lokal dan jarak jauh. Panduan ini menunjukkan cara mengintegrasikan CastPlayer ke dalam aplikasi media Anda.

Untuk mengintegrasikan Cast dengan platform lain, lihat Cast SDK.

Menambahkan CastPlayer sebagai dependensi

Untuk mulai menggunakan CastPlayer, tambahkan dependensi AndroidX Media3 dan CastPlayer yang Anda butuhkan dalam file build.gradle modul aplikasi Anda.

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"

Lihat catatan rilis Jetpack Media untuk menemukan rilis alfa terbaru sehingga Anda dapat mengintegrasikan CastPlayer ke dalam aplikasi. Semua modul harus memiliki versi yang sama.

Untuk mengetahui informasi selengkapnya tentang modul library yang tersedia, lihat halaman Google Maven AndroidX Media3.

Mengonfigurasi CastPlayer

Untuk mengonfigurasi CastPlayer, perbarui file AndroidManifest.xml Anda dengan penyedia opsi.

Penyedia opsi

CastPlayer memerlukan penyedia opsi untuk mengonfigurasi perilakunya. Untuk penyiapan dasar, Anda dapat menggunakan penyedia opsi default dengan menambahkannya ke file AndroidManifest.xml. Tindakan ini menggunakan setelan default, termasuk aplikasi penerima default.

<application>
  <meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
</application>

Untuk menyesuaikan konfigurasi, terapkan OptionsProvider kustom Anda sendiri. Lihat panduan CastOptions untuk mempelajari caranya.

Menambahkan penerima untuk transfer media

Menambahkan MediaTransferReceiver ke manifes memungkinkan UI Sistem mengalihkan media tanpa membuka aktivitas aplikasi. Misalnya, pengguna dapat mengubah perangkat yang memutar media aplikasi Anda dari notifikasi media.

<application>
  <receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
</application>

Membangun CastPlayer

Untuk pemutaran jarak jauh dengan Cast, aplikasi Anda harus dapat mengelola pemutaran meskipun pengguna tidak berinteraksi dengan Aktivitas dari aplikasi Anda, seperti melalui notifikasi media sistem. Oleh karena itu, Anda harus membuat instance ExoPlayer (untuk pemutaran lokal) dan CastPlayer (untuk pemutaran jarak jauh) di layanan, seperti MediaSessionService atau MediaLibraryService. Pertama, buat instance ExoPlayer, lalu saat membuat instance CastPlayer, tetapkan ExoPlayer sebagai instance pemutar lokal. Media3 kemudian akan dapat menangani transfer pemutar saat rute output berubah dari lokal ke jarak jauh atau dari jarak jauh ke lokal.

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();
}

Menambahkan elemen UI

Tambahkan MediaRouteButton ke UI aplikasi Anda agar pengguna dapat memilih perangkat Cast. Bagian ini menunjukkan cara menambahkan tombol dan memproses peristiwa untuk memperbarui UI saat pemutaran beralih antara perangkat lokal dan jarak jauh.

Menetapkan MediaRouteButton

Ada empat kemungkinan metode untuk menambahkan MediaRouteButton ke UI aktivitas agar pengguna dapat berinteraksi dengannya. Pilihan akan bergantung pada tampilan dan cara kerja UI untuk aktivitas pemutar yang Anda inginkan.

Menambahkan tombol rute media Composable ke Pemutar

Anda dapat menambahkan composable MediaRouteButton ke UI pemutar. Untuk informasi selengkapnya, lihat panduan penyusunan.

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) {
  ...
}

Menambahkan tombol rute media ke PlayerView

Anda dapat menambahkan MediaRouteButton langsung dalam kontrol UI PlayerView. Setelah menyetel MediaController sebagai pemutar untuk PlayerView, berikan MediaRouteButtonViewProvider untuk menampilkan tombol Cast di Pemutar.

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());
}

Menambahkan tombol rute media ke menu panel aplikasi

Metode ini menyiapkan tombol rute media di menu panel aplikasi. Pembaruan pada file manifes dan Activity diperlukan untuk menampilkan gaya tombol ini.

<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);
    ...
}

Menambahkan tombol rute media sebagai Tampilan

Atau, Anda dapat menyiapkan MediaRouteButton di layout.xml aktivitas Anda. Untuk menyelesaikan penyiapan MediaRouteButton, gunakan Media3 Cast MediaRouteButtonFactory dalam kode Activity Anda.

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);
}

Pemroses Aktivitas

Buat Player.Listener di Activity untuk memproses perubahan pada lokasi pemutaran media. Saat playbackType berubah antara PLAYBACK_TYPE_LOCAL dan PLAYBACK_TYPE_REMOTE, Anda dapat menyesuaikan UI sesuai kebutuhan. Untuk mencegah kebocoran memori dan membatasi aktivitas pemroses hanya saat aplikasi Anda terlihat, daftarkan pemroses di onStart dan batalkan pendaftarannya di onStop:

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);
}

Untuk mengetahui informasi selengkapnya tentang cara memproses dan merespons peristiwa pemutaran, lihat panduan peristiwa pemutar.