1- نظرة عامة
سيعلّمك هذا الدرس التطبيقي حول الترميز كيفية إنشاء تطبيق مستقبِل ويب مخصّص لتشغيل المحتوى على الأجهزة التي تمكّن تكنولوجيا Google Cast.
ما المقصود بـ Google Cast؟
يتيح Google Cast للمستخدمين إرسال المحتوى من جهاز جوّال إلى جهاز تلفزيون. ويمكن للمستخدمين بعد ذلك استخدام جهاز الجوّال أو متصفح Chrome على سطح المكتب كوحدة تحكم عن بُعد لتشغيل الوسائط على التلفزيون.
تسمح حزمة Google Cast SDK لتطبيقك بالتحكم في الأجهزة التي تعمل بتكنولوجيا Google Cast (على سبيل المثال، التلفزيون أو نظام الصوت). تزودك مجموعة أدوات Cast Cast بمكونات واجهة المستخدم الضرورية استنادًا إلى قائمة التحقق من تصميم Google Cast.
يتم توفير قائمة التحقق من تصميم Google Cast لتيسير تجربة المستخدم في Cast، كما يمكن التنبؤ بها عبر جميع الأنظمة الأساسية المتاحة. الاطّلاع على مزيد من المعلومات هنا
ما الذي سنبنيه؟
عند الانتهاء من هذا الدرس التطبيقي حول الترميز، سيصبح لديك تطبيق HTML5 يعمل كجهاز استقبال مخصّص يمكنه عرض محتوى الفيديو على الأجهزة التي تعمل بتكنولوجيا Google Cast.
ما ستتعرَّف عليه
- كيفية الإعداد لتطوير جهاز الاستقبال.
- أساسيات جهاز الاستقبال الذي يعمل بتكنولوجيا Google Cast استنادًا إلى إطار عمل تطبيق الإرسال.
- كيفية استلام فيديو تم إرساله
- كيفية دمج مسجِّل تصحيح الأخطاء.
- كيفية تحسين جهاز الاستقبال للشاشات الذكية
المتطلبات
- أحدث إصدار من متصفّح Google Chrome
- خدمة استضافة HTTPS مثل استضافة Firebase أو ngrok.
- جهاز Google Cast مثل Chromecast أو Android TV الذي تم إعداده للاستخدام مع الاتصال بالإنترنت.
- تلفزيون أو شاشة مزودة بمنفذ إدخال HDMI.
التجربة
- ستحتاج إلى معرفة سابقة بتطوير الويب.
- ستحتاج أيضًا إلى معرفة سابقة بمشاهدة التلفزيون :)
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربتك في إنشاء تطبيقات الويب؟
ما هو تقييمك لتجربتك في مشاهدة التلفزيون؟
2. الحصول على نموذج الشفرة
يمكنك تنزيل كل نماذج الشفرة إلى جهاز الكمبيوتر...
وفكّ ضغط الملف المضغوط الذي تم تنزيله.
3- نشر جهاز الاستقبال محليًا
حتى تتمكن من استخدام جهاز استقبال الويب مع جهاز بث، يجب أن يكون مستضافًا في مكان يمكن لجهاز البث الوصول إليه. إذا كان لديك خادم متوفر من قبل يدعم https، فتخط الإرشادات التالية ودوّن عنوان URL، حيث ستحتاج إليه في القسم التالي.
إذا لم يكن لديك خادم متاح للاستخدام، يمكنك استخدام استضافة Firebase أو ngrok.
تشغيل الخادم
بعد إعداد الخدمة التي تريدها، انتقل إلى app-start
وابدأ تشغيل الخادم.
دوِّن عنوان URL للمستلِم المستضاف. وستستخدمها في القسم التالي.
4. تسجيل تطبيق في Play Developer Console
يجب تسجيل تطبيقك لتتمكّن من تشغيل جهاز استقبال مخصّص، كما هو مضمّن في هذا الدرس التطبيقي حول الترميز، على أجهزة Chromecast. بعد تسجيل التطبيق، ستتلقى معرف التطبيق الذي يجب أن يستخدمه تطبيق المرسل لإجراء استدعاءات واجهة برمجة التطبيقات، مثل تشغيل تطبيق المتلقي.
انقر على "إضافة تطبيق جديد"
حدد "جهاز الاستقبال المخصص"، وهذا ما يتم إنشاؤه.
أدخِل تفاصيل المستلِم الجديد، وتأكَّد من استخدام عنوان URL الذي وصلت إليه في النهاية.
في القسم الأخير. دوّن رقم تعريف التطبيق الذي تم تعيينه للمستلم الجديد.
يجب عليك أيضًا تسجيل جهاز Google Cast حتى يتسنى له الدخول إلى تطبيق المتلقي قبل نشره. بعد نشر تطبيق الاستقبال، سيكون متاحًا على جميع أجهزة Google Cast. لغرض هذا الدرس التطبيقي حول الترميز، ننصحك باستخدام تطبيق استقبال غير منشور.
انقر على "إضافة جهاز جديد"
أدخل الرقم التسلسلي المطبوع على الجزء الخلفي من جهاز البث وامنحه اسمًا وصفيًا. يمكنك أيضًا العثور على الرقم التسلسلي من خلال إرسال الشاشة في Chrome عند الدخول إلى وحدة تحكم مطوّري البرامج في Google Cast SDK
سيستغرق الأمر من 5 إلى 15 دقيقة قبل أن يصبح جهاز الاستقبال والجهاز جاهزين للاختبار. بعد الانتظار من 5 إلى 15 دقيقة، يجب إعادة تشغيل جهاز البث.
5- تشغيل نموذج التطبيق
بينما ننتظر إلى أن يصبح تطبيق المُستلِم الجديد جاهزًا للاختبار، لنرى كيف يبدو نموذج تطبيق المُستلِم المكتمل. سيكون جهاز الاستقبال الذي سننشئه قادرًا على تشغيل الوسائط باستخدام بث معدل بت تكيُّفي (سنستخدم نموذج محتوى مرمَّز للبث الديناميكي التكيُّفي عبر HTTP (DASH)).
في المتصفِّح، افتح أداة الأمر والتحكُّم (CaC).
- من المفترض أن تظهر لك أداة CaC.
- استخدِم نموذج المُستلِم التلقائي "CC1AD845" وانقر على الزر "ضبط رقم تعريف التطبيق".
- انقر على زر الإرسال في أعلى اليمين وحدد جهاز Google Cast.
- انتقل إلى علامة التبويب "تحميل الوسائط" في الجزء العلوي.
- انقر على الزر "تحميل بحسب المحتوى" لتشغيل نموذج فيديو.
- سيبدأ تشغيل الفيديو على جهاز Google Cast لعرض كيف سيبدو أداء جهاز الاستقبال الأساسي باستخدام جهاز الاستقبال الافتراضي.
6. إعداد المشروع الافتتاحي
يجب إضافة Google Cast إلى بدء تشغيل التطبيق الذي نزّلته. في ما يلي بعض مصطلحات Google Cast التي سنستخدمها في هذا الدرس التطبيقي حول الترميز:
- يعمل تطبيق المُرسِل على جهاز جوّال أو كمبيوتر محمول،
- يعمل تطبيق مستلِم على جهاز Google Cast.
أنت الآن مستعد للبدء في العمل على مشروع المبتدئين باستخدام محرر النصوص المفضل لديك:
- اختَر الدليل
app-start
من نموذج تنزيل الرمز. - فتح
js/receiver.js
وindex.html
ملاحظة: أثناء عملك على هذا الدرس التطبيقي حول الترميز، على http-server
اختيار التغييرات التي تُجريها. إذا لاحظت أنه غير صحيح، حاول قتل http-server
ثم إعادة تشغيله.
تصميم التطبيق
يعمل تطبيق جهاز الاستقبال على تهيئة جلسة الإرسال وسيتم الاستعداد إلى أن يصل طلب التحميل (بعبارة أخرى، الأمر لتشغيل جزء من الوسائط) من المُرسِل.
يتكون التطبيق من عرض رئيسي واحد، محدد في index.html
وملف JavaScript واحد يُسمى js/receiver.js
يحتوي على كل المنطق لجعل جهاز الاستقبال يعمل.
index.html
سيتضمن ملف html واجهة المستخدم لتطبيق المُستلِم. إنه خالٍ الآن، وسنضيف إليه عبر مختبر الرموز.
pickupr.js
سيدير هذا النص البرمجي كل منطق تطبيق جهاز الاستقبال الذي نستخدمه حاليًا. فهو ملف فارغ الآن، ولكننا سنحوله إلى جهاز استقبال يعمل بشكل كامل مع تضمين بضعة أسطر من الشفرة في القسم التالي.
7- جهاز استقبال أساسي للإرسال
سيعمل جهاز استقبال البث الأساسي على إعداد جلسة البث عند بدء التشغيل. ويعد هذا ضروريًا لإخبار جميع تطبيقات المرسلين المتصلين التي تؤدي إلى استقبال المتلقي بنجاح. إضافةً إلى ذلك، تتوفّر حزمة تطوير البرامج (SDK) الجديدة التي تم ضبطها مسبقًا للتعامل مع وسائط بث معدل نقل البيانات التكيُّفي (باستخدام DASH وHLS وSmooth Streaming) وملفات MP4 عادية بشكل فوري. لنجرّب ذلك.
التهيئة
أضِف الرمز التالي إلى index.html
في العنوان:
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>
يُرجى إضافة الرمز التالي إلى index.html
<body>
قبل تحميل footer>
receiver.js,
لتزويد حزمة تطوير البرامج (SDK) للمستلِم بمساحة لجلب واجهة مستخدم المُستلِم التلقائية التي يتم شحنها باستخدام النص البرمجي الذي أضفته للتو.
<cast-media-player></cast-media-player>
الآن، نحتاج إلى إعداد SDK في js/receiver.js
، وتتألف من:
- الحصول على مرجع لـ
CastReceiverContext
، فإن نقطة الدخول الأساسية تشير إلى حزمة SDK الكاملة للمستلم - تخزين مرجع إلى
PlayerManager
، الكائن الذي يعالج الكائنات ويزودك بكل ما تحتاج إليه لتركيب المنطق وفقًا لرغبتك - تهيئة حزمة تطوير البرامج (SDK) من خلال استدعاء
start()
فيCastReceiverContext
إضافة ما يلي إلى js/receiver.js
.
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
context.start();
8. إرسال محتوى فيديو "أساسي"
لغرض هذا الدرس التطبيقي حول الترميز، استخدِم أداة CaC لتجربة جهاز الاستقبال الجديد.
وجّه متصفح الويب إلى أداة الأوامر والتحكم (CAC).
تأكد من استبدال معرّف التطبيق التابع لك كما هو مسجل سابقًا في الحقل، وانقر على "تعيين معرّف التطبيق". يؤدي هذا إلى توجيه الأداة لاستخدام جهاز الاستقبال عند بدء جلسة الإرسال.
بث الوسائط
على مستوى عالٍ، يجب تشغيل ما يلي لتشغيل الوسائط على جهاز بث:
- ينشئ المُرسِل كائن
MediaInfo
JSON
من Cast SDK الذي يُعد عنصر وسائط. - يتصل المُرسِل بجهاز البث لتشغيل تطبيق المُستلِم.
- يحمّل المستلِم الكائن
MediaInfo
من خلال طلبLOAD
لتشغيل المحتوى. - يراقب جهاز الاستقبال حالة الوسائط ويتتبعها.
- يرسل المُرسِل أوامر التشغيل إلى المُستلِم للتحكُّم في التشغيل استنادًا إلى تفاعلات المستخدم مع تطبيق المُرسِل.
في هذه المحاولة الأساسية الأولى، سنملأ MediaInfo
بعنوان URL لمادة العرض القابلة للتشغيل (المخزنة في MediaInfo.contentUrl
).
يستخدم مُرسِل حقيقي معرّف وسائط خاص بالتطبيق في MediaInfo.contentId
. يستخدم المستلِم contentId
كمعرّف لإجراء طلبات بيانات ملائمة من واجهة برمجة التطبيقات الخلفية لحلّ عنوان URL الفعلي لمادة العرض وضبطه على MediaInfo.contentUrl.
. سيعالج جهاز الاستقبال أيضًا مهام مثل الحصول على ترخيص DRM أو إدخال معلومات عن الفواصل الإعلانية.
سنعمل على توسيع نطاق المستلِم لتنفيذ إجراء كهذا في القسم التالي. في الوقت الحالي، انقر على رمز الإرسال وحدد جهازك لفتح جهاز الاستقبال.
انتقل إلى علامة التبويب "تحميل الوسائط" وانقر على الزر "تحميل المحتوى". من المفترض أن يبدأ المستلِم تشغيل نموذج المحتوى.
ولذلك، فإن مجموعة أدوات "المستلم" في حزمة SDK غير مباشرة:
- جارٍ إعداد جلسة الإرسال
- معالجة طلبات
LOAD
الواردة من مُرسِلين يحتويون على مواد عرض قابلة للتشغيل - توفير واجهة مستخدم أساسية للمشغّل جاهزة للعرض على الشاشة الكبيرة.
لا تتردد في استكشاف أداة CAC ورمزها قبل الانتقال إلى القسم التالي، حيث سنعمل على توسيع نطاق مستلمنا للتحدث إلى نموذج بسيط لواجهة برمجة التطبيقات لتلبية طلبات LOAD
الواردة من المرسلين.
9- الدمج مع واجهة برمجة تطبيقات خارجية
تماشيًا مع طريقة تفاعل معظم مطوّري البرامج مع أجهزة استقبال البث في التطبيقات الفعلية، سنعدّل جهاز الاستقبال لمعالجة طلبات LOAD
التي تشير إلى محتوى الوسائط المعنيّ من خلال مفتاح واجهة برمجة التطبيقات الخاص بها بدلاً من إرسال عنوان URL لمادة عرض قابلة للتشغيل.
عادةً ما تُجري التطبيقات هذا للأسباب التالية:
- قد لا يعرف المُرسِل عنوان URL للمحتوى.
- تم تصميم تطبيق Cast للتعامل مع المصادقة أو إجراءات الأنشطة التجارية الأخرى أو طلبات البيانات من واجهة برمجة التطبيقات مباشرةً على جهاز الاستقبال.
يتم تطبيق هذه الوظيفة بشكل أساسي في طريقة PlayerManager
setMessageInterceptor()
. يمكّنك هذا من اعتراض الرسائل الواردة حسب النوع وتعديلها قبل أن تصل إلى معالج الرسائل الداخلية لحزمة تطوير البرامج (SDK). في هذا القسم، سنتناول LOAD
طلبًا وسننفّذ ما يلي:
- اقرأ طلب
LOAD
الوارد وcontentId
المخصص له. - يمكنك استدعاء
GET
إلى واجهة برمجة التطبيقات للبحث عن مادة العرض القابلة للبث حسبcontentId
. - عدّل طلب
LOAD
باستخدام عنوان URL للبث. - عدِّل الكائن
MediaInformation
لضبط مَعلمات نوع البث. - مرّر الطلب إلى حزمة SDK للتشغيل، أو ارفض الأمر إذا لم نتمكن من البحث عن الوسائط المطلوبة.
تعرض واجهة برمجة التطبيقات للنماذج المقدمة عناصر الجذب لتخصيص مهام المتلقي الشائعة، مع الاستمرار في الاعتماد على تجربة مبسّطة غالبًا.
نموذج واجهة برمجة التطبيقات
وجّه المتصفح إلى https://storage.googleapis.com/cpe-sample-media/content.json وألقِ نظرة على عيّنة من كتالوج الفيديوهات. ويتضمن المحتوى عناوين URL لصور الملصقات بتنسيق png بالإضافة إلى كل من مجموعات بث DASH وHLS. وتشير مجموعات بث DASH وHLS إلى مصادر الفيديو والفيديوهات غير المُجمّعة المخزنة في حاويات mp4 مجزّأة.
{
"bbb": {
"author": "The Blender Project",
"description": "Grumpy Bunny is grumpy",
"poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
"stream": {
"dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
"hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
"title": "Big Buck Bunny"
},
"fbb_ad": {
"author": "Google Inc.",
"description": "Introducing Chromecast. The easiest way to enjoy [...]",
"poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
"stream": {
"dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
"hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
"title": "For Bigger Blazes"
},
[...]
}
في الخطوة التالية، سنربط مفتاح كل إدخال (على سبيل المثال، bbb, fbb_ad
) بعنوان URL الخاص بساحة المشاركات بعد اتصال المستلِم بطلب LOAD
.
اعتراض طلب LOAD
في هذه الخطوة، سنُنشئ أداة اعتراض على التحميل باستخدام وظيفة تجري طلب XHR
لملف JSON
المستضاف. بعد الحصول على الملف JSON
، سنحلّل المحتوى ونحدّد البيانات الوصفية. في الأقسام التالية سنخصص معلمات MediaInformation
لتحديد نوع المحتوى.
يُرجى إضافة الرمز التالي إلى ملف js/receiver.js
، قبل المكالمة مباشرةً إلى context.start()
.
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
reject();
} else {
// Add metadata
let metadata = new
cast.framework.messages.GenericMediaMetadata();
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
سيوضح القسم التالي كيفية تهيئة خاصية media
لطلب التحميل لمحتوى DASH.
استخدام نموذج محتوى DASH لواجهة برمجة التطبيقات
الآن وبعد إعداد أداة اعتراض التحميل، سنحدد نوع المحتوى لجهاز الاستقبال. ستوفر هذه المعلومات للمستلم عنوان URL لقائمة التشغيل الرئيسية ونوع بث MIME. أضِف الرمز التالي إلى ملف js/receiver.js في أداة اعتراض LOAD
لأداة Promise()
:
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
...
}
});
});
});
بعد إكمال هذه الخطوة، يمكنك المتابعة إلى "تجربة الميزة" لمحاولة التحميل باستخدام محتوى DASH. إذا أردت اختبار التحميل باستخدام محتوى HLS بدلاً من ذلك، اطّلِع على الخطوة التالية.
استخدام نموذج محتوى HLS لواجهة برمجة تطبيقات
يتضمن نموذج واجهة برمجة التطبيقات محتوى HLS بالإضافة إلى DASH. بالإضافة إلى ضبط contentType
كما فعلنا في الخطوة السابقة، سيحتاج طلب التحميل إلى بعض الخصائص الإضافية من أجل استخدام نماذج عناوين URL لـ HLS في واجهة برمجة التطبيقات. عند إعداد جهاز الاستقبال لتشغيل مجموعات البث المباشر وفق بروتوكول HTTP، يكون نوع الحاوية التلقائي المتوقع هو النقل (TS). نتيجةً لذلك، سيحاول المستلِم فتح نموذج لعمليات بث MP4 بتنسيق TS إذا تم تعديل السمة contentUrl
فقط. في طلب التحميل، يجب تعديل الكائن MediaInformation
بخصائص إضافية حتى يعرف المُستلِم أن المحتوى من النوع MP4 وليس TS. أضِف الرمز التالي إلى ملف js/receiver.js في أداة اعتراض التحميل لتعديل السمتَين contentUrl
وcontentType
. إضافةً إلى ذلك، يُرجى إضافة الخاصيتين HlsSegmentFormat
وHlsVideoSegmentFormat
.
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.hls;
request.media.contentType = 'application/x-mpegurl';
request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
...
}
});
});
});
اختبار الميزة
افتح مرة أخرى أداة الأوامر والتحكم (CaC) وعيِّن رقم تعريف التطبيق لمعرِّف تطبيق المستلم. حدد جهازك باستخدام زر الإرسال.
انتقل إلى علامة التبويب "تحميل الوسائط". في هذه المرة، احذف النص في حقل "عنوان URL للمحتوى" بجوار الزر "تحميل المحتوى"، مما سيفرض إرسال طلب LOAD
الذي يحتوي على مرجع contentId
فقط إلى الوسائط.
على افتراض أنّ كل شيء سار على ما يرام مع التعديلات على جهاز الاستقبال، يجب أن يعتني برنامج الاعتراض بتشكيل الكائن MediaInfo
في شيء يمكن أن تُشغِّله حزمة تطوير البرامج (SDK) على الشاشة.
انقر على الزر "تحميل بحسب المحتوى" لمعرفة ما إذا كانت الوسائط تعمل بشكل صحيح أم لا. لا تتردد في تغيير معرّف المحتوى إلى معرّف آخر في ملف content.json.
10- التحسين من أجل الشاشات الذكية
الشاشات الذكية هي أجهزة مزوّدة بوظيفة لمس تسمح لتطبيقات الاستقبال أن تدعم عناصر التحكّم التي تعمل باللمس.
يوضح هذا القسم كيفية تحسين تطبيق جهاز الاستقبال عند تشغيله على الشاشات الذكية وكيفية تخصيص عناصر التحكّم في المشغّل.
الوصول إلى عناصر التحكم في واجهة المستخدم
يمكن الوصول إلى كائن "عناصر التحكم في واجهة المستخدم" للشاشات الذكية باستخدام cast.framework.ui.Controls.GetInstance()
. أضف الرمز التالي إلى ملف js/receiver.js
أعلى context.start()
:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
context.start();
إذا كنت لا تستخدم العنصر <cast-media-player>، فسيلزمك تعيين touchScreenOptimizedApp
في CastReceiverOptions
. في هذا الدرس التطبيقي حول الترميز، نستخدم العنصر <cast-media-player>.
context.start({ touchScreenOptimizedApp: true });
يتم تخصيص أزرار التحكّم التلقائية لكل خانة بناءً على MetadataType
وMediaStatus.supportedMediaCommands
.
عناصر التحكم في الفيديو
بالنسبة إلى MetadataType.MOVIE
وMetadataType.TV_SHOW
وMetadataType.GENERIC
، سيتم عرض كائن عناصر التحكم في واجهة المستخدم على الشاشات الذكية كما في المثال أدناه.
--playback-logo-image
MediaMetadata.subtitle
MediaMetadata.title
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.QUEUE_PREV
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.SEEK_BACKWARD_30
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.SEEK_FORWARD_30
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.QUEUE_NEXT
عناصر التحكم في الصوت
بالنسبة إلى MetadataType.MUSIC_TRACK
، سيتم عرض كائن "عناصر التحكم في واجهة المستخدم" للشاشات الذكية على النحو التالي:
--playback-logo-image
MusicTrackMediaMetadata.albumName
MusicTrackMediaMetadata.title
MusicTrackMediaMetadata.albumArtist
MusicTrackMediaMetadata.images[0]
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.NO_BUTTON
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.QUEUE_PREV
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.QUEUE_NEXT
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.NO_BUTTON
تحديث أوامر الوسائط المدعومة
يحدد كائن عناصر التحكم في واجهة المستخدم أيضًا ما إذا كان سيتم عرض ControlsButton
أم لا بناءً على MediaStatus.supportedMediaCommands
.
عندما تساوي قيمة supportedMediaCommands
ALL_BASIC_MEDIA
، سيتم عرض تنسيق عنصر التحكّم التلقائي على النحو التالي:
عندما تساوي قيمة supportedMediaCommands
ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT
، سيتم عرض تنسيق عنصر التحكّم التلقائي على النحو التالي:
عندما تساوي قيمة أمر MediaMediaCommands PAUSE | QUEUE_PREV | QUEUE_NEXT
، سيتم عرض تنسيق عنصر التحكم التلقائي كما يلي:
عند توفّر المقاطع الصوتية النصية، سيظهر زر الترجمة والشرح دائمًا على SLOT_1
.
لتغيير قيمة supportedMediaCommands
ديناميكيًا بعد بدء سياق المُستقبِل، يمكنك استدعاء PlayerManager.setSupportedMediaCommands
لإلغاء القيمة. يمكنك أيضًا إضافة أمر جديد باستخدام addSupportedMediaCommands
أو إزالة أمر حالي باستخدام removeSupportedMediaCommands
.
تخصيص أزرار التحكم
يمكنك تخصيص عناصر التحكم باستخدام PlayerDataBinder
. أضف الرمز التالي إلى ملف js/receiver.js
أسفل touchControls لتعيين الفتحة الأولى لعناصر التحكم:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
});
context.start();
11- تنفيذ تصفُّح الوسائط على الشاشات الذكية
"تصفح الوسائط" هي ميزة مستقبِل CAF تتيح للمستخدمين استكشاف محتوى إضافي على الأجهزة التي تعمل باللمس. لتنفيذ هذا الإجراء، عليك استخدام PlayerDataBinder
لضبط واجهة مستخدم BrowseContent
. يمكنك بعد ذلك تعبئته بـ BrowseItems
استنادًا إلى المحتوى الذي تريد عرضه.
تصفُّح المحتوى
في ما يلي مثال على واجهة مستخدم BrowseContent
وخصائصها:
BrowseContent.title
BrowseContent.items
نسبة العرض إلى الارتفاع
استخدِم targetAspectRatio property
لاختيار أفضل نسبة عرض إلى ارتفاع لمواد عرض الصور. تتوفّر ثلاث نسب عرض إلى ارتفاع من خلال حزمة تطوير البرامج (SDK) الخاصة باستلام أجهزة CAF وهي: SQUARE_1_TO_1
وPORTRAIT_2_TO_3
وLANDSCAPE_16_TO_9
.
تصفُّح العنصر
يمكنك استخدام BrowseItem
لعرض العنوان والعنوان الفرعي والمدة والصورة لكل سلعة:
BrowseItem.image
BrowseItem.duration
BrowseItem.title
BrowseItem.subtitle
تعيين بيانات تصفح الوسائط
يمكنك تقديم قائمة بمحتوى الوسائط للتصفُّح من خلال الاتصال بالرقم setBrowseContent
. أضِف الرمز التالي إلى ملف js/receiver.js
أسفل playerDataBinder
، وفي أداة معالجة حدث MEDIA_CHANGED
لضبط عناصر التصفّح بعنوان "التالي".
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
...
let browseItems = getBrowseItems();
function getBrowseItems() {
let browseItems = [];
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
});
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
....
// Media browse
touchControls.setBrowseContent(browseContent);
});
يؤدي النقر على عنصر تصفح الوسائط إلى تشغيل أداة اعتراض LOAD
. أضف الرمز التالي إلى أداة اعتراض LOAD
لربط request.media.contentId
بعنصر request.media.entity
من تصفح الوسائط:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
...
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
...
});
});
يمكنك أيضًا ضبط الكائن BrowseContent
على null
لإزالة واجهة مستخدم "تصفُّح الوسائط".
12- تصحيح أخطاء تطبيقات المستلِم
توفر حزمة SDK لجهاز استقبال Cast خيارًا آخر لمطوّري البرامج لتصحيح أخطاء تطبيقات جهاز الاستقبال بسهولة باستخدام واجهة برمجة تطبيقات CastDebugLogger وأداة Command وCaC مصاحبة لالتقاط السجلات.
الإعداد
لدمج واجهة برمجة التطبيقات، أضِف النص البرمجي المصدر CastDebugLogger
في ملف index.html. يجب الإعلان عن المصدر في العلامة <head> بعد إعلان SDK لجهاز الإرسال.
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<!-- Cast Debug Logger -->
<script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>
في js/receiver.js
في أعلى الملف وأسفل playerManager
، أضِف الرمز التالي لاسترداد مثيل CastDebugLogger
وتفعيل أداة التسجيل:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
عند تفعيل مسجِّل تصحيح الأخطاء، سيظهر تراكب يعرض DEBUG MODE
على جهاز الاستقبال.
تسجيل أحداث المشغل
باستخدام CastDebugLogger
، يمكنك بسهولة تسجيل أحداث المشغّل التي تم تنشيطها بواسطة حزمة تطوير البرامج لجهاز استقبال CAF واستخدام مستويات مسجّل مختلفة لتسجيل بيانات الأحداث. يستخدم إعداد loggerLevelByEvents
cast.framework.events.EventType
وcast.framework.events.category
لتحديد الأحداث التي سيتم تسجيلها.
أضِف الرمز التالي أسفل تعريف castDebugLogger
لتسجيله عند تشغيل حدث CORE
للاعب أو عند بث تغيير mediaStatus
:
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
تسجيل الرسائل والعلامات المخصصة
تسمح لك واجهة برمجة تطبيقات CastDebugLogger بإنشاء رسائل سجلّ تظهر على تراكب تصحيح أخطاء المستلِم بألوان مختلفة. تتوفر طرق السجل التالية، مدرجة بالترتيب من الأولوية القصوى إلى الأولوية الدنيا:
castDebugLogger.error(custom_tag, message);
castDebugLogger.warn(custom_tag, message);
castDebugLogger.info(custom_tag, message);
castDebugLogger.debug(custom_tag, message);
بالنسبة إلى كل طريقة سجل، تكون المعلمة الأولى هي علامة مخصصة. يمكن أن يكون ذلك أي سلسلة تعريفية تجدها ذات مغزى. يستخدم CastDebugLogger
العلامات لفلترة السجلات. يتم شرح استخدام العلامات بالتفصيل أدناه. المعلمة الثانية هي رسالة السجل.
لعرض السجلات عمليًا، أضِف سجلّات إلى أداة اعتراض LOAD
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error(LOG_TAG, 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);
// Add metadata
let metadata = new cast.framework.messages.MovieMediaMetadata();
metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
يمكنك التحكُّم في الرسائل التي تظهر على تراكب تصحيح الأخطاء عن طريق ضبط مستوى السجلّ في loggerLevelByTags
لكل علامة مُخصَّصة. على سبيل المثال، سيؤدي تفعيل علامة مخصّصة على مستوى السجلّ cast.framework.LoggerLevel.DEBUG
إلى عرض جميع الرسائل التي تمت إضافتها مع ظهور رسائل الخطأ والتحذير والمعلومات وتصحيح الأخطاء في السجلّ. سيؤدي تفعيل علامة مخصّصة بمستوى WARNING
إلى عرض رسائل الخطأ والتحذير في السجلّ فقط.
تهيئة loggerLevelByTags
اختيارية. في حال عدم ضبط علامة مخصّصة على مستوى المسجِّل، سيتم عرض جميع رسائل السجلّ على تراكب تصحيح الأخطاء.
أضِف الرمز التالي أسفل مسجِّل الأحداث CORE
:
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
[LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};
تراكب تصحيح الأخطاء
توفّر أداة "تسجيل تصحيح أخطاء الإرسال" تراكبًا لتصحيح الأخطاء على جهاز الاستقبال لعرض رسائل السجلّ المخصصة على جهاز البث. يمكنك استخدام showDebugLogs
لتبديل تراكب تصحيح الأخطاء وclearDebugLogs
لمحو رسائل السجل على التراكب.
أضف الرمز التالي لمعاينة تراكب تصحيح الأخطاء على جهاز الاستقبال.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);
// Show debug overlay
castDebugLogger.showDebugLogs(true);
// Clear log messages on debug overlay
castDebugLogger.clearDebugLogs();
}
});
13- تهانينا
أنت تعرف الآن كيفية إنشاء تطبيق مخصّص لاستقبال الويب باستخدام حزمة SDK لجهاز استقبال الويب من Cast.
لمزيد من التفاصيل، راجع دليل مطوري برامج مستقبل الويب.