1- نظرة عامة
سيعلّمك هذا الدرس التطبيقي حول كيفية تعديل تطبيق حالي على Android TV لإتاحة البث والتواصل من تطبيقات الإرسال الحالية التي تعمل بنظام التشغيل Cast.
ما هما Google Cast وCast Connect؟
يسمح تطبيق Google Cast للمستخدمين ببث المحتوى من جهاز جوّال إلى تلفزيون. تتألف جلسة Google Cast النموذجية من مكوّنَين: المُرسِل وتطبيق المستلِم. تبدأ تطبيقات المُرسِل، مثل تطبيق متوافق مع الأجهزة الجوّالة أو موقع إلكتروني، مثل YouTube.com، في تشغيل أحد تطبيقات استقبال البث والتحكم فيها. تطبيقات استقبال البث هي تطبيقات HTML 5 التي يتم تشغيلها على أجهزة Chromecast وAndroid TV.
يتم تخزين كل الولاية تقريبًا في جلسة البث على تطبيق المستلِم. عند تعديل الحالة، على سبيل المثال، في حال تحميل عنصر وسائط جديد، يتم بث حالة وسائط لجميع المُرسِلين. تحتوي عمليات البث هذه على الحالة الحالية لجلسة البث. تستخدم تطبيقات المُرسِل حالة الوسائط هذه لعرض معلومات التشغيل في واجهة المستخدم.
يستند تطبيق Cast Connect إلى هذه البنية الأساسية، حيث يعمل تطبيق Android TV كمستلِم. تسمح مكتبة Cast Connect لتطبيق Android TV بتلقّي الرسائل وحالة بث الوسائط كما لو أنها تطبيق لجهاز استقبال البث.
ما الذي سنبنيه؟
عند إكمال هذا الدرس التطبيقي حول الترميز، ستتمكّن من استخدام تطبيقات إرسال البث لبث فيديوهات إلى تطبيق Android TV. ويمكن أيضًا لتطبيق Android TV التواصل مع تطبيقات المُرسِل من خلال بروتوكول البث.
ما ستتعرَّف عليه
- كيفية إضافة مكتبة Cast Connect إلى نموذج تطبيق ATV
- كيفية ربط مُرسِل بث وتشغيل تطبيق ATV
- طريقة بدء تشغيل الوسائط على تطبيق ATV من تطبيق Cast Cast
- طريقة إرسال حالة الوسائط من تطبيق ATV إلى تطبيقات Cast Cast
المتطلبات
- أحدث إصدار من حزمة تطوير البرامج (SDK) لنظام التشغيل Android
- أحدث إصدار من Android Studio على وجه التحديد،
Chipmunk | 2021.2.1
أو إصدارات أحدث. - جهاز Android TV فعّل خيارات مطوّري البرامج وتصحيح أخطاء USB
- هاتف Android تم تفعيل خيارات المطوّرين وتصحيح الأخطاء عبر USB فيه
- كابل بيانات بمنفذ USB لتوصيل هاتف Android وأجهزة Android TV بجهاز الكمبيوتر المخصص للتطوير.
- المعرفة الأساسية بتطوير تطبيقات Android باستخدام لغة Kotlin.
2- الحصول على الرمز النموذجي
يمكنك تنزيل كل الرموز البرمجية على جهاز الكمبيوتر...
وفك ضغط ملف ZIP الذي تم تنزيله.
3. تشغيل نموذج التطبيق
أولاً، لنتعرّف على شكل نموذج التطبيق المكتمل. يستخدم تطبيق Android TV واجهة مستخدم iGoogle ومشغّل فيديو أساسي. ويمكن للمستخدم اختيار فيديو من قائمة يتم تشغيلها بعد ذلك على التلفزيون عند اختيارها. ومن خلال التطبيق المرفق مع جهاز الجوّال، يمكن للمستخدم أيضًا بث فيديو على تطبيق Android TV.
تسجيل أجهزة مطوّري البرامج
لتفعيل إمكانات Cast Connect لتطوير التطبيقات، يجب تسجيل الرقم التسلسلي لجهاز Chromecast Built-in المضمّن في الجهاز والذي ستستخدمه في Play Developer Console. يمكنك العثور على الرقم التسلسلي من خلال الانتقال إلى الإعدادات > إعدادات الجهاز المفضّلة > مضمّن Chromecast > الرقم التسلسلي على Android TV. وتجدر الإشارة إلى أنّ هذا الرقم يختلف عن الرقم التسلسلي لجهازك ويجب الحصول عليه من الطريقة الموضّحة أعلاه.
لأسباب تتعلق بالأمان، لن يعمل تطبيق Cast Connect إلا مع التطبيقات المثبّتة من "متجر Google Play". بعد مرور 15 دقيقة من بدء عملية التسجيل، أعِد تشغيل جهازك.
تثبيت تطبيق مُرسِل Android
لاختبار طلبات الإرسال من جهاز جوّال، قدّمنا تطبيق إرسال بسيطًا يُسمى "بث الفيديوهات" كملف mobile-sender-0629.apk
في ملف ZIP الذي تم تنزيله باستخدام رمز المصدر. سنستعين بأداة ADB لتثبيت حزمة APK. إذا سبق لك تثبيت إصدار مختلف من فيديوهات البث، يُرجى إلغاء تثبيت هذا الإصدار من كل الملفات الشخصية المتوفرة على الجهاز قبل المتابعة.
- فعِّل خيارات المطوّرين وتصحيح الأخطاء عبر USB على هاتف Android.
- وصِّل كابل بيانات USB لتوصيل هاتف Android بجهاز التطوير.
- ثبِّت
mobile-sender-0629.apk
على هاتف Android.
- يمكنك العثور على تطبيق مُرسِل بث الفيديوهات على هاتف Android الخاص بك.
تثبيت تطبيق Android TV
توضّح التعليمات التالية كيفية فتح نموذج التطبيق المكتمل وتشغيله في "استوديو Android":
- اختَر استيراد المشروع على شاشة الترحيب أو قائمة الخيارات ملف > جديد > استيراد المشروع....
- اختَر الدليل
app-done
من مجلد الرمز النموذجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle.
- فعِّل خيارات المطوّرين وتصحيح الأخطاء عبر USB على جهاز Android TV.
- يجب توصيل ADB بجهاز Android TV، ومن المفترض أن يظهر الجهاز في "استوديو Android".
- انقر على الزر
Run (تشغيل)، من المفترض أن يظهر لك تطبيق ATV بعنوان Cast Connect Codelab بعد بضع ثوانٍ.
لنشغِّل بث Cast Connect باستخدام تطبيق ATV
- انتقِل إلى الشاشة الرئيسية في Android TV.
- افتح تطبيق مُرسِل فيديوهات البث من هاتف Android. انقر على زر البث
واختَر جهاز ATV.
- سيتم تشغيل تطبيق Cast Connect Code ATV على جهاز ATV، وسيشير زر البث في المُرسِل إلى أنه متصل
.
- اختَر فيديو من تطبيق ATV وسيبدأ تشغيل الفيديو على جهاز ATV.
- على هاتفك الجوّال، تظهر وحدة تحكّم مصغّرة الآن في أسفل تطبيق المُرسِل. ويمكنك استخدام زر التشغيل/الإيقاف المؤقت للتحكّم في التشغيل.
- اختَر فيديو من الهاتف الجوّال وابدأ اللعب. سيبدأ تشغيل الفيديو على جهاز ATV وسيتم عرض وحدة التحكّم الموسَّعة على مُرسِل الجهاز الجوّال.
- عليك قفل هاتفك وعند فتح قفله، سيظهر لك إشعار على شاشة القفل للتحكّم في تشغيل الوسائط أو إيقاف البث.
4- إعداد مشروع البدء
الآن بعد أن تأكّدنا من دمج تطبيق Cast Connect المكتملة، نحتاج إلى إضافة التوافق إلى Cast Connect إلى التطبيق الذي نزّلته. بعد أن أصبحت جاهزًا للبدء في العمل على مشروع المبتدئين باستخدام "استوديو Android":
- اختَر استيراد المشروع على شاشة الترحيب أو قائمة الخيارات ملف > جديد > استيراد المشروع....
- اختَر الدليل
app-start
من مجلد الرمز النموذجي وانقر على "حسنًا". - انقر على ملف >
مزامنة المشروع مع ملفات Gradle.
- اختَر جهاز ATV، ثم انقر على الزر
تشغيل لتشغيل التطبيق واستكشاف واجهة المستخدم.
تصميم التطبيقات
يوفر التطبيق قائمة بالفيديوهات التي يمكن للمستخدم تصفّحها. يمكن للمستخدمين اختيار فيديو لتشغيله على Android TV. يتكون التطبيق من نشاطَين رئيسيَين: MainActivity
وPlaybackActivity
.
MainActivity
يحتوي هذا النشاط على جزء (MainFragment
). يتم ضبط قائمة الفيديوهات والبيانات الوصفية المرتبطة بها ضمن الفئة MovieList
ويتم استدعاء الطريقة setupMovies()
لإنشاء قائمة من العناصر Movie
.
يمثل الكائن Movie
كيان فيديو يتضمن عنوانًا ووصفًا وإبهام الصورة وعنوان URL للفيديو. يقتصر كل عنصر Movie
على CardPresenter
لتقديم صورة مصغّرة للفيديو مع العنوان والاستوديو ويتم تمريرها إلى ArrayObjectAdapter
.
عند اختيار عنصر، يتم تمرير عنصر Movie
المقابل إلى PlaybackActivity
.
نشاط التشغيل
يحتوي هذا النشاط على جزء (PlaybackVideoFragment
) يستضيف VideoView
مع ExoPlayer
، وبعض عناصر التحكّم في الوسائط، ومنطقة نصية لعرض وصف الفيديو المحدّد ويسمح للمستخدم بتشغيل الفيديو على Android TV. يمكن للمستخدم استخدام جهاز التحكّم عن بُعد لتشغيل/إيقاف الفيديوهات مؤقتًا أو البحث عن طريقة لتشغيل الفيديوهات.
المتطلّبات الأساسية لتطبيق Cast Connect
تستخدم ميزة Cast Connect إصدارات جديدة من "خدمات Google Play" تتطلّب تحديث تطبيق ATV لاستخدام مساحة الاسم AndroidX.
لإتاحة Cast Connect في تطبيق Android TV، يجب إنشاء أحداث ودعم من جلسة وسائط. تعمل مكتبة Cast Connect على إنشاء حالة الوسائط استنادًا إلى حالة جلسة الوسائط. تستخدم مكتبة Cast Connect أيضًا جلسة الوسائط للإشارة إلى تلقّيها رسائل معيّنة من أحد المُرسِلين، مثل الإيقاف المؤقت.
5. ضبط إعدادات فريق دعم البث
المهام التابعة
عدِّل ملف التطبيق build.gradle
لتضمين الاعتماديات اللازمة في المكتبة:
dependencies {
....
// Cast Connect libraries
implementation 'com.google.android.gms:play-services-cast-tv:20.0.0'
implementation 'com.google.android.gms:play-services-cast:21.1.0'
}
يمكنك مزامنة المشروع لتأكيد إنشاء المشروع بدون أخطاء.
الإعداد
CastReceiverContext
هو كائن فردي لتنسيق جميع تفاعلات البث. يجب تنفيذ واجهة ReceiverOptionsProvider
لتوفير CastReceiverOptions
عند إعداد CastReceiverContext
.
أنشئ ملف CastReceiverOptionsProvider.kt
وأضِف الصف التالي إلى المشروع:
package com.google.sample.cast.castconnect
import android.content.Context
import com.google.android.gms.cast.tv.ReceiverOptionsProvider
import com.google.android.gms.cast.tv.CastReceiverOptions
class CastReceiverOptionsProvider : ReceiverOptionsProvider {
override fun getOptions(context: Context): CastReceiverOptions {
return CastReceiverOptions.Builder(context)
.setStatusText("Cast Connect Codelab")
.build()
}
}
بعد ذلك، حدِّد موفِّر خيارات المستلِم ضمن علامة <application>
في ملف AndroidManifest.xml
للتطبيق:
<application>
...
<meta-data
android:name="com.google.android.gms.cast.tv.RECEIVER_OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.castconnect.CastReceiverOptionsProvider" />
</application>
للاتصال بتطبيق ATV من مُرسِل البث، اختَر نشاطًا تريد تشغيله. في هذا الدرس التطبيقي حول الترميز، سنطلق تطبيق MainActivity
عند بدء جلسة البث. في الملف AndroidManifest.xml
، أضِف فلتر أهداف الإطلاق في MainActivity
.
<activity android:name=".MainActivity">
...
<intent-filter>
<action android:name="com.google.android.gms.cast.tv.action.LAUNCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
مراحل نشاط جهاز استقبال البث
يجب بدء علامة "CastReceiverContext
" عند تشغيل التطبيق وإيقاف "CastReceiverContext
" عند نقله إلى الخلفية. نقترح استخدام LifecycleObserver
من مكتبة androidx.lifecycle لإدارة الاتصال في CastReceiverContext.start()
وCastReceiverContext.stop()
.
افتح ملف MyApplication.kt
، وعليك إعداد سياق البث عن طريق استدعاء initInstance()
في طريقة onCreate
للتطبيق. في الفئة AppLifeCycleObserver
start()
، يجب CastReceiverContext
عند استئناف التطبيق وstop()
عند إيقاف التطبيق مؤقتًا:
package com.google.sample.cast.castconnect
import com.google.android.gms.cast.tv.CastReceiverContext
...
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
CastReceiverContext.initInstance(this)
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
}
class AppLifecycleObserver : DefaultLifecycleObserver {
override fun onResume(owner: LifecycleOwner) {
Log.d(LOG_TAG, "onResume")
CastReceiverContext.getInstance().start()
}
override fun onPause(owner: LifecycleOwner) {
Log.d(LOG_TAG, "onPause")
CastReceiverContext.getInstance().stop()
}
}
}
ربط MediaSession بحساب MediaManager
MediaManager
هي إحدى سمات بروتوكول CastReceiverContext
سينغلتون، وتدير حالة الوسائط، وتعالج هدف التحميل، وتترجم رسائل مساحة اسم الوسائط من المُرسِلين إلى أوامر الوسائط، وتُعيد حالة الوسائط إلى المُرسِلين.
عند إنشاء MediaSession
، عليك أيضًا تقديم الرمز المميّز الحالي لتطبيق MediaSession
إلى MediaManager
ليتمكّن من معرفة مكان إرسال الأوامر واسترجاع حالة تشغيل الوسائط. في ملف PlaybackVideoFragment.kt
، تأكّد من إعداد MediaSession
قبل ضبط الرمز المميّز على MediaManager
.
import com.google.android.gms.cast.tv.CastReceiverContext
import com.google.android.gms.cast.tv.media.MediaManager
...
class PlaybackVideoFragment : VideoSupportFragment() {
private var castReceiverContext: CastReceiverContext? = null
...
private fun initializePlayer() {
if (mPlayer == null) {
...
mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager: MediaManager = castReceiverContext!!.getMediaManager()
mediaManager.setSessionCompatToken(mMediaSession!!.getSessionToken())
}
}
}
}
عند إصدار MediaSession
بسبب تشغيل غير نشط، يجب ضبط رمز مميز فارغ على MediaManager
:
private fun releasePlayer() {
mMediaSession?.release()
castReceiverContext?.mediaManager?.setSessionCompatToken(null)
...
}
لنشغّل نموذج التطبيق
انقر على الزر تشغيل لنشر التطبيق على جهاز ATV، ثم إغلاق التطبيق والعودة إلى شاشة ATV الرئيسية. من المُرسِل، انقر على زر البث
واختَر جهاز ATV الخاص بك. سيظهر لك أنّه تم تشغيل التطبيق على جهاز ATV وربط زر البث.
6- جارٍ تحميل الوسائط
يتم إرسال أمر التحميل من خلال هدف يتضمن اسم الحزمة الذي حددته في Play Console. يجب إضافة فلتر الأهداف المحدّد مسبقًا التالي في تطبيق Android TV لتحديد النشاط المستهدف الذي سيتلقّى هذا الهدف. في ملف AndroidManifest.xml
، أضِف فلتر أهداف التحميل إلى PlayerActivity
:
<activity android:name="com.google.sample.cast.castconnect.PlaybackActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.cast.tv.action.LOAD"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
التعامل مع طلبات التحميل على Android TV
الآن بعد أن تم إعداد النشاط بحيث يتلقّى هذا الهدف عن طريق طلب تحميل، سنحتاج إلى التعامل معه.
يستدعي التطبيق طريقة خاصة باسم processIntent
عند بدء النشاط. تتضمّن هذه الطريقة طريقة معالجة الأهداف الواردة. لمعالجة طلب التحميل، سنعدّل هذه الطريقة ونرسل النية بالشراء لإجراء المزيد من المعالجة من خلال استدعاء طريقة onNewIntent
التابعة للمثيل MediaManager
. إذا اكتشف MediaManager
أنّ الهدف من طلبات التحميل هو مُستخرَج كائن MediaLoadRequestData
من الهدف واستدعاء MediaLoadCommandCallback.onLoad()
. عدِّل طريقة processIntent
في الملف PlaybackVideoFragment.kt
للتعامل مع intent التي تحتوي على طلب التحميل:
fun processIntent(intent: Intent?) {
val mediaManager: MediaManager = CastReceiverContext.getInstance().getMediaManager()
// Pass intent to Cast SDK
if (mediaManager.onNewIntent(intent)) {
return
}
// Clears all overrides in the modifier.
mediaManager.getMediaStatusModifier().clear()
// If the SDK doesn't recognize the intent, handle the intent with your own logic.
...
}
بعد ذلك، سيتم توسيع الصف المجرّد MediaLoadCommandCallback
الذي سيلغي طريقة onLoad()
التي تم طلبها من خلال MediaManager
. تتلقّى هذه الطريقة بيانات طلب التحميل وتحوّلها إلى عنصر Movie
. وبعد تحويله، يتم تشغيل الفيلم من قِبل المشغّل المحلي. بعد ذلك، يتم تعديل MediaManager
من خلال MediaLoadRequest
وبث MediaStatus
إلى المُرسِلين المرتبطين. أنشئ صفًا خاصًا مدمجًا باسم MyMediaLoadCommandCallback
في ملف PlaybackVideoFragment.kt
:
import com.google.android.gms.cast.MediaLoadRequestData
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaError
import com.google.android.gms.cast.tv.media.MediaException
import com.google.android.gms.cast.tv.media.MediaCommandCallback
import com.google.android.gms.cast.tv.media.QueueUpdateRequestData
import com.google.android.gms.cast.tv.media.MediaLoadCommandCallback
import com.google.android.gms.tasks.Task
import com.google.android.gms.tasks.Tasks
import android.widget.Toast
...
private inner class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
override fun onLoad(
senderId: String?, mediaLoadRequestData: MediaLoadRequestData): Task<MediaLoadRequestData> {
Toast.makeText(activity, "onLoad()", Toast.LENGTH_SHORT).show()
return if (mediaLoadRequestData == null) {
// Throw MediaException to indicate load failure.
Tasks.forException(MediaException(
MediaError.Builder()
.setDetailedErrorCode(MediaError.DetailedErrorCode.LOAD_FAILED)
.setReason(MediaError.ERROR_REASON_INVALID_REQUEST)
.build()))
} else Tasks.call {
play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
// Update media metadata and state
val mediaManager = castReceiverContext!!.mediaManager
mediaManager.setDataFromLoad(mediaLoadRequestData)
mediaLoadRequestData
}
}
}
private fun convertLoadRequestToMovie(mediaLoadRequestData: MediaLoadRequestData?): Movie? {
if (mediaLoadRequestData == null) {
return null
}
val mediaInfo: MediaInfo = mediaLoadRequestData.getMediaInfo() ?: return null
var videoUrl: String = mediaInfo.getContentId()
if (mediaInfo.getContentUrl() != null) {
videoUrl = mediaInfo.getContentUrl()
}
val metadata: MediaMetadata = mediaInfo.getMetadata()
val movie = Movie()
movie.videoUrl = videoUrl
movie.title = metadata?.getString(MediaMetadata.KEY_TITLE)
movie.description = metadata?.getString(MediaMetadata.KEY_SUBTITLE)
if(metadata?.hasImages() == true) {
movie.cardImageUrl = metadata.images[0].url.toString()
}
return movie
}
الآن بعد تحديد معاودة الاتصال، يجب تسجيلها في MediaManager
. يجب أن تكون معاودة الاتصال مسجَّلة قبل أن يتم استدعاء MediaManager.onNewIntent()
. إضافة setMediaLoadCommandCallback
عند إعداد المشغّل:
private fun initializePlayer() {
if (mPlayer == null) {
...
mMediaSession = MediaSessionCompat(getContext(), LOG_TAG)
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
mediaManager.setSessionCompatToken(mMediaSession.getSessionToken())
mediaManager.setMediaLoadCommandCallback(MyMediaLoadCommandCallback())
}
}
}
لنشغّل نموذج التطبيق
انقر على الزر Run (تشغيل) لنشر التطبيق على جهاز ATV. من المُرسِل، انقر على زر البث
واختَر جهاز ATV الخاص بك. سيتم تشغيل تطبيق ATV على جهاز ATV. اختَر فيديو على الجهاز الجوّال، وسيبدأ تشغيل الفيديو على جهاز ATV. تحقَّق من تلقّي إشعار على هاتفك يتضمّن عناصر التحكّم في التشغيل. جرِّب استخدام عناصر التحكّم مثل الإيقاف المؤقت، ويجب إيقاف الفيديو على جهاز ATV مؤقتًا.
7- إتاحة أوامر التحكّم في البث
يتيح التطبيق الحالي الآن استخدام الأوامر الأساسية المتوافقة مع جلسة وسائط، مثل التشغيل والإيقاف المؤقت وتقديم التقديم. ومع ذلك، لا تتوفّر بعض أوامر التحكّم في البث في جلسة الوسائط. عليك تسجيل جهاز MediaCommandCallback
لإتاحة أوامر التحكّم في البث هذه.
إضافة MyMediaCommandCallback
إلى المثيل MediaManager
باستخدام setMediaCommandCallback
عند إعداد المشغّل:
private fun initializePlayer() {
...
castReceiverContext = CastReceiverContext.getInstance()
if (castReceiverContext != null) {
val mediaManager = castReceiverContext!!.mediaManager
...
mediaManager.setMediaCommandCallback(MyMediaCommandCallback())
}
}
يمكنك إنشاء فئة MyMediaCommandCallback
لإلغاء الطرق، مثل onQueueUpdate()
لتوفير أوامر التحكّم في البث هذه:
private inner class MyMediaCommandCallback : MediaCommandCallback() {
override fun onQueueUpdate(
senderId: String?,
queueUpdateRequestData: QueueUpdateRequestData
): Task<Void> {
Toast.makeText(getActivity(), "onQueueUpdate()", Toast.LENGTH_SHORT).show()
// Queue Prev / Next
if (queueUpdateRequestData.getJump() != null) {
Toast.makeText(
getActivity(),
"onQueueUpdate(): Jump = " + queueUpdateRequestData.getJump(),
Toast.LENGTH_SHORT
).show()
}
return super.onQueueUpdate(senderId, queueUpdateRequestData)
}
}
8- التعامل مع حالة الوسائط
تعديل حالة الوسائط
يحصل Cast Connect على حالة الوسائط الأساسية من جلسة الوسائط. لإتاحة الميزات المتقدّمة، يمكن لتطبيق Android TV تحديد سمات الحالة الإضافية وإلغائها من خلال MediaStatusModifier
. سيتم تشغيل MediaStatusModifier
دائمًا على MediaSession
التي ضبطتها في CastReceiverContext
.
على سبيل المثال، لتحديد setMediaCommandSupported
عندما يتم تشغيل استدعاء onLoad
:
import com.google.android.gms.cast.MediaStatus
...
private class MyMediaLoadCommandCallback : MediaLoadCommandCallback() {
fun onLoad(
senderId: String?,
mediaLoadRequestData: MediaLoadRequestData
): Task<MediaLoadRequestData> {
Toast.makeText(getActivity(), "onLoad()", Toast.LENGTH_SHORT).show()
...
return Tasks.call({
play(convertLoadRequestToMovie(mediaLoadRequestData)!!)
...
// Use MediaStatusModifier to provide additional information for Cast senders.
mediaManager.getMediaStatusModifier()
.setMediaCommandSupported(MediaStatus.COMMAND_QUEUE_NEXT, true)
.setIsPlayingAd(false)
mediaManager.broadcastMediaStatus()
// Return the resolved MediaLoadRequestData to indicate load success.
mediaLoadRequestData
})
}
}
الاعتراض على حالة الوسائط قبل الإرسال
كما هو الحال مع MessageInterceptor
لحزمة تطوير البرامج (SDK) الخاصة بالمستلم على الويب، يمكنك تحديد MediaStatusWriter
في MediaManager
لإجراء تعديلات إضافية على MediaStatus
قبل بثه إلى المرسلين المتصلين.
مثلاً، يمكنك إعداد البيانات المخصّصة في MediaStatus
قبل إرسالها إلى جهات إرسال الأجهزة الجوّالة:
import com.google.android.gms.cast.tv.media.MediaManager.MediaStatusInterceptor
import com.google.android.gms.cast.tv.media.MediaStatusWriter
import org.json.JSONObject
import org.json.JSONException
...
private fun initializePlayer() {
if (mPlayer == null) {
...
if (castReceiverContext != null) {
...
val mediaManager: MediaManager = castReceiverContext.getMediaManager()
...
// Use MediaStatusInterceptor to process the MediaStatus before sending out.
mediaManager.setMediaStatusInterceptor(
MediaStatusInterceptor { mediaStatusWriter: MediaStatusWriter ->
try {
mediaStatusWriter.setCustomData(JSONObject("{myData: 'CustomData'}"))
} catch (e: JSONException) {
Log.e(LOG_TAG,e.message,e);
}
})
}
}
}
9. تهانينا
أصبحت الآن تعرف كيفية تفعيل تطبيق Android TV المفعَّل فيه البث باستخدام "مكتبة البث".
يمكنك الاطّلاع على دليل المطوّر للحصول على مزيد من التفاصيل: /cast/docs/android_tv_ ستتلقىr.