CastPlayer là một phương thức triển khai Player của Jetpack Media3, hỗ trợ cả tính năng phát cục bộ và truyền đến một thiết bị từ xa có hỗ trợ Cast. CastPlayer giúp đơn giản hoá việc thêm chức năng truyền vào ứng dụng của bạn và cung cấp nhiều tính năng để chuyển đổi liền mạch giữa chế độ phát cục bộ và phát từ xa. Hướng dẫn này trình bày cách tích hợp CastPlayer vào ứng dụng đa phương tiện của bạn.
Để tích hợp Cast với các nền tảng khác, hãy xem Cast SDK.
Thêm CastPlayer làm phần phụ thuộc
Để bắt đầu sử dụng CastPlayer, hãy thêm các phần phụ thuộc AndroidX Media3 và CastPlayer cần thiết vào tệp build.gradle của mô-đun ứng dụng.
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"
Tham khảo ghi chú phát hành Jetpack Media để tìm bản phát hành alpha mới nhất để bạn có thể tích hợp CastPlayer vào ứng dụng của mình. Tất cả các mô-đun phải có cùng phiên bản.
Để biết thêm thông tin về các mô-đun thư viện hiện có, hãy xem trang Google Maven AndroidX Media3.
Định cấu hình CastPlayer
Để định cấu hình CastPlayer, hãy cập nhật tệp AndroidManifest.xml bằng một trình cung cấp lựa chọn.
Nhà cung cấp lựa chọn
CastPlayer yêu cầu một nhà cung cấp tuỳ chọn để định cấu hình hành vi của nó. Đối với chế độ thiết lập cơ bản, bạn có thể sử dụng trình cung cấp lựa chọn mặc định bằng cách thêm trình cung cấp này vào tệp AndroidManifest.xml. Thao tác này sử dụng chế độ cài đặt mặc định, bao gồm cả ứng dụng nhận mặc định.
<application>
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="androidx.media3.cast.DefaultCastOptionsProvider" />
</application>
Để tuỳ chỉnh cấu hình, hãy triển khai OptionsProvider tuỳ chỉnh của riêng bạn.
Hãy xem hướng dẫn về CastOptions để tìm hiểu cách thực hiện.
Thêm một receiver để chuyển nội dung nghe nhìn
Việc thêm MediaTransferReceiver vào tệp kê khai cho phép Giao diện người dùng hệ thống định tuyến lại nội dung nghe nhìn mà không cần mở hoạt động của ứng dụng. Ví dụ: người dùng có thể thay đổi thiết bị phát nội dung nghe nhìn của ứng dụng thông qua thông báo về nội dung nghe nhìn.
<application>
<receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
</application>
Tạo CastPlayer
Đối với tính năng phát từ xa bằng Cast, ứng dụng của bạn phải có khả năng quản lý hoạt động phát ngay cả khi người dùng không tương tác với một Hoạt động trong ứng dụng của bạn, chẳng hạn như thông qua thông báo của hệ thống về nội dung nghe nhìn. Vì lý do này, bạn nên tạo các thực thể ExoPlayer (để phát cục bộ) và CastPlayer (để phát từ xa) trong một dịch vụ, chẳng hạn như MediaSessionService hoặc MediaLibraryService. Trước tiên, hãy tạo thực thể ExoPlayer, sau đó khi tạo thực thể CastPlayer, hãy đặt ExoPlayer làm thực thể trình phát cục bộ. Sau đó, Media3 sẽ có thể xử lý các hoạt động chuyển trình phát khi tuyến đầu ra thay đổi từ cục bộ sang từ xa hoặc từ từ xa sang cục bộ.
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(); }
Thêm các phần tử trên giao diện người dùng
Thêm một MediaRouteButton vào giao diện người dùng của ứng dụng để cho phép người dùng chọn một thiết bị truyền.
Phần này hướng dẫn bạn cách thêm nút và theo dõi các sự kiện để cập nhật giao diện người dùng khi chế độ phát chuyển đổi giữa thiết bị cục bộ và thiết bị từ xa.
Đặt MediaRouteButton
Có 4 phương thức có thể dùng để thêm MediaRouteButton vào giao diện người dùng của hoạt động để người dùng tương tác. Lựa chọn này sẽ phụ thuộc vào cách bạn muốn giao diện người dùng cho hoạt động của trình phát xuất hiện và hoạt động.
Thêm nút tuyến đường nội dung nghe nhìn có thể kết hợp vào Trình phát
Bạn có thể thêm thành phần kết hợp MediaRouteButton vào giao diện người dùng của trình phát. Để biết thêm thông tin, hãy xem hướng dẫn về 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) { ... }
Thêm nút tuyến phát nội dung nghe nhìn vào PlayerView
Bạn có thể thêm MediaRouteButton ngay trong các chế độ điều khiển giao diện người dùng của PlayerView. Sau khi đặt MediaController làm trình phát cho PlayerView, hãy cung cấp một MediaRouteButtonViewProvider để hiển thị nút Truyền trên Trình phát.
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()); }
Thêm nút tuyến đường truyền nội dung nghe nhìn vào trình đơn thanh ứng dụng
Phương thức này thiết lập một nút tuyến đường truyền thông trong trình đơn thanh ứng dụng. Bạn cần cập nhật cả tệp kê khai và Activity để hiển thị kiểu nút này.
<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); ... }
Thêm nút tuyến đường truyền phát nội dung nghe nhìn dưới dạng một View
Ngoài ra, bạn có thể thiết lập một MediaRouteButton trong activity layout.xml.
Để hoàn tất quá trình thiết lập cho MediaRouteButton, hãy sử dụng MediaRouteButtonFactory Media3 Cast trong mã Activity của bạn.
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); }
Trình nghe hoạt động
Tạo một Player.Listener trong Activity để theo dõi các thay đổi về vị trí phát nội dung nghe nhìn. Khi playbackType thay đổi giữa PLAYBACK_TYPE_LOCAL và PLAYBACK_TYPE_REMOTE, bạn có thể điều chỉnh giao diện người dùng nếu cần. Để ngăn chặn tình trạng rò rỉ bộ nhớ và giới hạn hoạt động của trình nghe chỉ khi ứng dụng của bạn hiển thị, hãy đăng ký trình nghe trong onStart và huỷ đăng ký trong 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); }
Để biết thêm thông tin về cách theo dõi và phản hồi các sự kiện phát, hãy xem hướng dẫn về sự kiện của trình phát.