CastPlayer 是 Jetpack Media3 Player 的實作項目,支援本機播放和投放至遠端支援 Cast 的裝置。CastPlayer
可簡化在應用程式中新增 Cast 功能的程序,並提供豐富的功能,讓使用者在本地和遠端播放之間順暢切換。本指南說明如何將 CastPlayer 整合至媒體應用程式。
如要將 Cast 與其他平台整合,請參閱 Cast SDK。
將 CastPlayer 新增為依附元件
如要開始使用 CastPlayer,請在應用程式模組的 build.gradle 檔案中,新增所需的 AndroidX Media3 和 CastPlayer 依附元件。
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"
請參閱 Jetpack Media 版本說明,找出最新 Alpha 版,以便將 CastPlayer 整合至應用程式。所有模組必須是相同版本。
如要進一步瞭解可用的程式庫模組,請參閱「Google Maven AndroidX Media3 頁面」。
設定 CastPlayer
如要設定 CastPlayer,請使用選項供應商更新 AndroidManifest.xml 檔案。
選項供應商
CastPlayer 需要選項供應器來設定其行為。如要進行基本設定,您可以將預設選項提供者新增至 AndroidManifest.xml 檔案。這會使用預設設定,包括預設接收器應用程式。
<application>
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
</application>
如要自訂設定,請實作自己的自訂 OptionsProvider。如要瞭解如何設定,請參閱 CastOptions 指南。
新增媒體轉移接收器
在資訊清單中新增 MediaTransferReceiver,即可讓系統 UI 重新導向媒體,不必開啟應用程式活動。舉例來說,使用者可以透過媒體通知,變更播放應用程式媒體的裝置。
<application>
<receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
</application>
建構 CastPlayer
如要使用 Cast 進行遠端播放,即使使用者未與應用程式的活動互動 (例如透過系統媒體通知),應用程式也應能管理播放作業。因此,您應在服務 (例如 MediaSessionService 或 MediaLibraryService) 中建立 ExoPlayer (用於本機播放) 和 CastPlayer (用於遠端播放) 執行個體。首先,請建立 ExoPlayer 例項,然後在建構 CastPlayer 例項時,將 ExoPlayer 設為本機播放器例項。這樣一來,當輸出路徑從本機變更為遠端,或從遠端變更為本機時,Media3 就能處理播放器轉移作業。
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 元素
在應用程式的 UI 中新增 MediaRouteButton,讓使用者選取 Cast 裝置。
本節說明如何新增按鈕及監聽事件,以便在播放作業於本機和遠端裝置之間切換時更新 UI。
設定 MediaRouteButton
您可以透過四種方法,將 MediaRouteButton 新增至活動的 UI,供使用者互動。選擇方式取決於您希望玩家活動的 UI 外觀和運作方式。
在播放器中新增可組合的媒體路徑按鈕
您可以將 MediaRouteButton 可組合函式新增至播放器的 UI。詳情請參閱 Compose 指南。
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) { ... }
將媒體路線按鈕新增至 PlayerView
你可以在 PlayerView 的 UI 控制項中直接新增 MediaRouteButton。將 MediaController 設為 PlayerView 的播放器後,請提供 MediaRouteButtonViewProvider,在播放器上顯示 Cast 按鈕。
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()); }
在應用程式列選單中新增媒體路線按鈕
這個方法會在應用程式列選單中設定媒體路線按鈕。如要顯示這種樣式的按鈕,必須更新資訊清單檔案和 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) ... }
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); ... }
將媒體路線按鈕新增為 View
或者,您也可以在活動 layout.xml 中設定 MediaRouteButton。
如要完成 MediaRouteButton 的設定,請在 Activity 程式碼中使用 Media3 Cast MediaRouteButtonFactory。
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); }
活動監聽器
在 Activity 中建立 Player.Listener,監聽媒體播放位置的變更。當 playbackType 在 PLAYBACK_TYPE_LOCAL 和 PLAYBACK_TYPE_REMOTE 之間切換時,您可以視需要調整 UI。為避免記憶體流失,並將事件監聽器活動限制在應用程式顯示時,請在 onStart 中註冊事件監聽器,並在 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); }
如要進一步瞭解如何監聽及回應播放事件,請參閱播放器事件指南。