CastPlayer هي عملية تنفيذ لمشغّل Jetpack Media3 Player تتيح تشغيل المحتوى محليًا وإرساله إلى جهاز بعيد يتيح استخدام Google Cast. CastPlayer
تسهّل إضافة وظيفة البث إلى تطبيقك وتوفّر ميزات متطورة للتبديل السلس بين التشغيل المحلي والتشغيل عن بُعد. يوضّح لك هذا الدليل كيفية دمج CastPlayer في تطبيق موسيقى.
لدمج Cast مع منصات أخرى، يُرجى الاطّلاع على Cast SDK.
الحصول على جهاز يتيح استخدام Google Cast
لاختبار CastPlayer، تحتاج إلى جهاز يتيح استخدام Google Cast. تشمل الخيارات Android TV وChromecast ومكبرات الصوت الذكية والشاشات الذكية. تأكَّد من إعداد جهازك واتصاله بشبكة Wi-Fi نفسها المتصل بها جهازك الجوّال المخصّص للتطوير من أجل اكتشافه.
إضافة تبعيات الإصدار
لبدء استخدام CastPlayer، أضِف تبعيات AndroidX Media3 وCastPlayer إلى ملف build.gradle الخاص بوحدة تطبيقك.
Kotlin
implementation("androidx.media3:media3-exoplayer:1.10.0")
implementation("androidx.media3:media3-ui:1.10.0")
implementation("androidx.media3:media3-session:1.10.0")
implementation("androidx.media3:media3-cast:1.10.0")
أنيق
implementation "androidx.media3:media3-exoplayer:1.10.0"
implementation "androidx.media3:media3-ui:1.10.0"
implementation "androidx.media3:media3-session:1.10.0"
implementation "androidx.media3:media3-cast:1.10.0"
ضبط CastPlayer
لضبط CastPlayer، عدِّل ملف AndroidManifest.xml باستخدام موفّر خيارات.
موفّر الخيارات
يتطلب CastPlayer موفّر خيارات لضبط سلوكه. لإجراء إعداد
أساسي، يمكنك استخدام DefaultCastOptionsProvider من خلال إضافته إلى ملف
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 إلى ملف البيان لواجهة مستخدِم النظام اكتشاف الأجهزة التي تتيح استخدام Google Cast على الشبكة وإعادة توجيه الوسائط بدون فتح النشاط على التطبيق. على سبيل المثال، يمكن للمستخدم تغيير الجهاز الذي يشغّل وسائط تطبيقك
من إشعار الوسائط.
<application>
...
<receiver android:name="androidx.mediarouter.media.MediaTransferReceiver" />
...
</application>
إنشاء CastPlayer
لتشغيل المحتوى عن بُعد باستخدام Cast، يجب أن يكون تطبيقك قادرًا على إدارة التشغيل حتى عندما لا يتفاعل المستخدم مع أحد الأنشطة من تطبيقك، مثلاً من خلال إشعار الوسائط في النظام. لهذا السبب، عليك إنشاء مثيلات
ExoPlayer (لتشغيل المحتوى محليًا) و CastPlayer (لتشغيل المحتوى عن بُعد)
في خدمة، مثل MediaSessionService أو MediaLibraryService.
أولاً، أنشئ مثيل ExoPlayer، ثم عند إنشاء مثيل
CastPlayer، اضبط ExoPlayer كمثيل المشغّل المحلي. يمكنك بعد ذلك تبديل تشغيل الوسائط بين جهازك الجوّال والجهاز الذي يتيح استخدام Google Cast من إشعار الوسائط أو إشعار شاشة القفل. تستخدم 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(); }
إضافة عناصر واجهة المستخدم
أضِف MediaRouteButton إلى واجهة مستخدم تطبيقك. يؤدي النقر على MediaRouteButton إلى فتح مربّع حوار يعرض قائمة بالأجهزة التي تتيح استخدام Google Cast المتاحة على الشبكة. عندما يختار المستخدم جهازًا، يتم نقل تشغيل الوسائط من الجهاز الجوّال إلى جهاز المستلِم المحدّد. يوضّح لك هذا القسم كيفية إضافة الزر والاستماع إلى الأحداث لتعديل واجهة المستخدم عند تبديل التشغيل بين الأجهزة المحلية والبعيدة.
ضبط MediaRouteButton
هناك أربع طرق لإضافة MediaRouteButton إلى واجهة مستخدم نشاطك. يعتمد الخيار الأفضل على تصميم تطبيقك ومتطلباته.
- واجهة مستخدم Compose: أضِف عنصرًا قابلاً للإنشاء للزر.
- واجهة مستخدم "العرض":
- أضِف الزر إلى قائمة شريط التطبيق.
- أضِف الزر داخل
PlayerView. - أضِف الزر كـ
Viewعادي.
إضافة عنصر MediaRouteButton قابل للإنشاء إلى المشغّل
يمكنك إضافة عنصر MediaRouteButton القابل للإنشاء إلى واجهة مستخدم المشغّل. لمزيد من
المعلومات، يُرجى الاطّلاع على دليل 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) { // ... }
إضافة MediaRouteButton إلى PlayerView
يمكنك إضافة MediaRouteButton مباشرةً ضمن PlayerViewعناصر التحكّم في واجهة المستخدم. بعد ضبط 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()); }
إضافة MediaRouteButton إلى قائمة شريط التطبيق
لإعداد MediaRouteButton في قائمة شريط التطبيق، أنشئ قائمة بتنسيق XML و
ألغِ onCreateOptionsMenu في 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; }
إضافة MediaRouteButton كـ View
يمكنك إعداد MediaRouteButton في ملف 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" />
لإكمال إعداد MediaRouteButton، استخدِم Media3 Cast
MediaRouteButtonFactory في رمز Activity البرمجي.
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); }
متتبِّع النشاط
أنشئ Player.Listener في Activity للاستماع إلى التغييرات في موقع تشغيل الوسائط. عندما يتغيّر playbackType بين PLAYBACK_TYPE_LOCAL وPLAYBACK_TYPE_REMOTE، يمكنك تعديل واجهة المستخدم حسب الحاجة. لمنع تسرّب الذاكرة وحصر نشاط المتتبِّع في الحالات التي يكون فيها تطبيقك مرئيًا فقط، سجِّل المتتبِّع في onStart وألغِ تسجيله في 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); }
لمزيد من المعلومات حول الاستماع إلى أحداث التشغيل والاستجابة لها، يُرجى الاطّلاع على دليل أحداث المشغّل.