1- نظرة عامة
يشرح لك هذا الدرس التطبيقي حول الترميز كيفية إنشاء تطبيق مخصّص لاستقبال الويب لتشغيل المحتوى على الأجهزة التي تعمل بتكنولوجيا Google Cast.
ما المقصود بـ Google Cast؟
تتيح تكنولوجيا Google Cast للمستخدمين بث المحتوى من جهاز جوّال إلى تلفزيون. ويمكن للمستخدمين بعد ذ��ك استخدام متصفّح Chrome على جهاز جوّال أو كمبيوتر مكتبي كوحدة تحكّم عن بُعد لتشغيل الوسائط على التلفزيون.
تسمح حزمة Google Cast SDK لتطبيقك بالتحكّم في الأجهزة التي تعمل بتكنولوجيا Google Cast (على سبيل المثال، التلفزيون أو نظام الصوت). تزودك حزمة تطوير البرامج (SDK) بتكنولوجيا Google Cast بمكوّنات واجهة المستخدم الضرورية بناءً على قائمة التحقق من تصميم Google Cast.
يتم توفير قائمة التحقق من تصميم Google Cast لتسهيل تجربة المستخدم على تكنولوجيا Google Cast على جميع الأنظمة الأساسية المتوافقة. مزيد من المعلومات
ما الذي سنبنيه؟
عند الانتهاء من هذا الدرس التطبيقي حول الترميز، سيكون لديك تطبيق HTML5 يعمل كـ جهاز استقبال مخصّص خاص بك ويمكنه عرض محتوى الفيديو على الأجهزة التي تعمل بتكنولوجيا Google Cast.
ما ستتعرَّف عليه
- كيفية الإعداد لتطوير جهاز الاستقبال
- أساسيات جهاز الاستقبال الذي يعمل بتكنولوجيا Google Cast على أساس إطار عمل تطبيق Cast.
- كيفية استلام فيديو تم إرساله
- كيفية دمج مسجّل تصحيح الأخطاء
- طريقة تحسين جهاز الاستقبال ليتوافق مع الشاشات الذكية
المتطلبات
- أحدث إصدار من متصفِّح Google Chrome.
- خدمة استضافة HTTPS، مثل استضافة Firebase أو ngrok.
- جهاز Google Cast، مثل Chromecast أو Android TV تم ضبطه على الاتصال بالإنترنت
- تلفزيون أو شاشة بها منفذ إدخال HDMI
التجربة
- يجب أن تكون لديك معرفة سابقة بتطوير الويب.
- ستحتاج أيضًا إلى معرفة سابقة بمشاهدة التلفزيون :)
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربتك في إنشاء تطبيقات الويب؟
ما هو تقييمك لتجربتك في مشاهدة التلفزيون؟
2. الحصول على الرمز النموذجي
يمكنك تنزيل جميع الرموز النموذجية على الكمبيوتر...
وفك ضغط الملف الذي تم تنزيله.
3. نشر جهاز الاستقبال محليًا
لتتمكن من استخدام جهاز استقبال الويب مع جهاز بث، يجب استضافته في مكان يمكن لجهاز البث من خلاله الوصول إليه. إذا كان لديك خادم يتيح لك استخدام https، يمكنك تخطّي التعليمات التالية وتدوين عنوان URL، لأنّه ستحتاج إليه في القسم التالي.
إذا لم يكن لديك خادم متاح للاستخدام، يمكنك استخدام استضافة Firebase أو ngrok.
تشغيل الخادم
بعد إعداد الخدمة التي تختارها، انتقِل إلى app-start
ثم شغِّل الخادم.
دوِّن عنوان URL للمستلِم المستضاف. ستستخدمها في القسم التالي.
4. تسجيل تطبيق في Google Cast Console
يجب تسجيل تطبيقك لتشغيل جهاز استقبال مخصّص، كما هو موضّح في هذا الدرس التطبيقي حول الترميز، على أجهزة Chromecast. بعد تسجيل تطبيقك، ستتلقى معرّف تطبيق يجب أن يستخدمه تطبيق المرسِل لإجراء طلبات بيانات من واجهة برمجة التطبيقات، مثل تشغيل تطبيق جهاز استقبال.
انقر على "إضافة تطبيق جديد".
حدد "Custom Replyr (مستلم مخصص)"، فهذا هو ما نصممه.
أدخل تفاصيل المُستلِم الجديد، واحرص على استخدام عنوان URL الذي انتهى المطاف به
في القسم الأخير. دوِّن معرّف التطبيق الذي تم تعيينه للمستلِم الجديد.
يجب أيضًا تسجيل جهاز Google Cast حتى يتمكن من الوصول إلى تطبيق المُستلِم قبل نشره. بعد نشر تطبيق جهاز الاستقبال، سيصبح متاحًا لجميع أجهزة Google Cast. لأغراض هذا الدرس التطبيقي حول الترميز، يُنصح باستخدام تطبيق مستلِم غير منشور.
عليك النقر على "إضافة جهاز جديد".
أدخِل الرقم التسلسلي المطبوع على الجزء الخلفي من جهاز البث وأدخِل اسمًا وصفيًا له. يمكنك أيضًا العثور على الرقم التسلسلي من خلال بث محتوى شاشتك في Chrome عند الدخول إلى Google Cast SDK Developer Console.
سيستغرق الأمر من 5 إلى 15 دقيقة قبل أن يصبح جهاز الاستقبال والجهاز جاهزين للاختبار. بعد الانتظار من 5 إلى 15 دقيقة، يجب إعادة تشغيل جهاز البث.
5. تشغيل نموذج التطبيق
في الوقت الذي ننتظر فيه أن يصبح تطبيق المُستلِم الجديد جاهزًا للاختبار، لنرَ ما يبدو عليه نموذج تطبيق الاستقبال المكتمل. سيتمكن جهاز الاستقبال الذي سننشئه من تشغيل الوسائط باستخدام بث معدل نقل بيانات تكيُّفي (سنستخدم نموذج محتوى مشفَّرًا للبث الديناميكي التكيُّفي عبر HTTP (DASH).
في متصفّحك، افتح أداة Command and Control (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 هذا على واجهة المستخدم لتطبيق جهاز الاستقبال. وهو في الوقت الحالي فارغ، وسنضيف إليه خلال مختبر التعليمات البرمجية.
receiver.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 لتجربة جهاز الاستقبال الجديد.
وجِّه متصفّح الويب إلى أداة Command and Control (CaC).
احرِص على استبدال رقم تعريف التطبيق كما هو مسجَّل سابقًا في الحقل، ثم انقر على "ضبط رقم تعريف التطبيق". يتم توجيه الأداة إلى استخدام جهاز الاستقبال عند بدء جلسة البث.
بث الوسائط
على مستوى عالٍ، يجب تنفيذ ما يلي لتشغيل الوسائط على جهاز بث:
- ينشئ المرسِل عنصر
JSON
MediaInfo
من حزمة تطوير البرامج (SDK) للإرسال والذي ينشئ نموذجًا لعنصر وسائط. - يتصل المرسِل بجهاز البث لتشغيل تطبيق جهاز الاستقبال.
- يحمّل المُستلِم العنصر
MediaInfo
من خلال طلبLOAD
لتشغيل المحتوى. - يراقب جهاز الاستقبال حالة الوسائط ويتتبّعها.
- يرسل المرسِل أوامر التشغيل إلى المتلقي للتحكم في التشغيل بناءً على تفاعلات المستخدم مع تطبيق المرسِل.
في هذه المحاولة الأساسية الأولى، سنملأ MediaInfo
بعنوان URL لمادة عرض قابلة للتشغيل (مخزَّن في MediaInfo.contentUrl
).
يستخدم المرسِل في العالم الفعلي معرّف وسائط خاصًا بالتطبيق في MediaInfo.contentId
. يستخدم المستلِم contentId
كمعرّف لإجراء طلبات البيانات المناسبة من واجهة برمجة التطبيقات للخلفية لحل عنوان URL الفعلي لمادة العرض وضبطه على MediaInfo.contentUrl.
. وسيعالج المستلِم أيضًا مهام مثل الحصول على ترخيص إدارة الحقوق الرقمية أو إدخال معلومات عن الفواصل الإعلانية.
سنعمل على توسيع نطاق جهاز الاستقبال لإجراء شيء مشابه لذلك في القسم التالي. في الوقت الحالي، انقر على رمز الإرسال واختَر جهازك لفتح جهاز الاستقبال.
انتقل إلى علامة التبويب "تحميل الوسائط" وانقر على الزر "تحميل حسب المحتوى". من المفترض أن يبدأ المُستلِم تشغيل عيّنة المحتوى.
لذا، تكون أدوات SDK لجهاز الاستقبال جاهزة للاستخدام:
- جارٍ إعداد جلسة البث
- معالجة طلبات "
LOAD
" الواردة من المُرسِلين الذين لديهم مواد عرض قابلة للتشغيل - توفير واجهة مستخدم أساسية للمشغّل جاهزة للعرض على الشاشة الكبيرة.
ننصحك بالاطّلاع على أداة CaC ورمزها قبل الانتقال إلى القسم التالي، حيث سنوسّع نطاق عمل المُستلِم من أجل التحدّث إلى نموذج بسيط من واجهة برمجة التطبيقات لتلبية طلبات LOAD
الواردة من المُرسِلين.
9. الدمج مع واجهة برمجة تطبيقات خارجية
تماشيًا مع الطريقة التي يتفاعل به�� ��ع��م ال��طو��ر��ن ��ع ��جهزة استقبال البث في التطبيقات الفعلية، سنعدّل جهاز الاستقبال للتعامل مع طلبات LOAD
التي تشير إلى محتوى الوسائط المقصود من خلال مفتاح واجهة برمجة التطبيقات بدلاً من إرسال عنوان URL لمادة عرض قابلة للتشغيل.
عادةً ما يحدث ذلك للأسباب التالية:
- قد لا يعرف المُرسِل عنوان URL للمحتوى.
- تم تصميم تطبيق Cast للتعامل مع المصادقة أو منطق العمل الآخر أو طلبات البيانات من واجهة برمجة التطبيقات على جهاز الاستقبال مباشرةً.
يتم تنفيذ هذه الوظيفة بشكل أساسي في طريقة PlayerManager
setMessageInterceptor()
. ويمكّنك هذا من اعتراض الرسائل الواردة حسب النوع وتعديلها قبل أن تصل إلى معالج الرسائل الداخلي في حزمة تطوير البرامج (SDK). في هذا القسم، نتعامل مع طلبات LOAD
حيث سيتم إجراء ما يلي:
- اقرأ طلب
LOAD
الوارد وإعداداتcontentId
المخصّصة له. - يمكنك إجراء اتصال
GET
بواجهة برمجة التطبيقات للبحث عن مادة العرض القابلة للبث بحلولcontentId
. - يمكنك تعديل طلب "
LOAD
" باستخدام عنوان URL الخاص بالبث. - عدِّل العنصر
MediaInformation
لضبط المَعلمات الخاصة بنوع البث. - مرِّر الطلب إلى حزمة تطوير البرامج (SDK) للتشغيل، أو ارفض الأمر إذا لم نتمكن من البحث عن الوسائط المطلوبة.
يعرض نموذج واجهة برمجة التطبيقات الذي تم تقديمه عناصر الجذب في حزمة تطوير البرامج (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
.
اعتراض طلب التحميل
سننشئ في هذه الخطوة أداة اعتراض التحميل تحتوي على دالة تُجري طلب 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/replyr.js في عنصر Promise()
لاعتراض LOAD
:
...
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 في واجهة برمجة التطبيقات. عند إعداد المُستلِم لتشغيل مجموعات بث HLS، يكون نوع الحاوية التلقائي المتوقّع هو بث النقل (TS). نتيجةً لذلك، سيحاول المستلِم فتح نماذج البث بتنسيق MP4 بتنسيق TS فقط إذا تم تعديل سمة contentUrl
. في طلب التحميل، يجب تعديل العنصر MediaInformation
بخصائص إضافية حتى يعرف المُستلِم أنّ المحتوى من النوع MP4 وليس من النوع TS. أضِف الرمز التالي إلى ملف js/replyr.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 ID إلى معرّف آخر في ملف 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
، سيتم عرض تنسيق عنصر التحكّم التلقائي على النحو التالي:
عندما تساوي قيمة SupportMediaCommands PAUSE | QUEUE_PREV | QUEUE_NEXT
، سيظهر تنسيق التحكّم التلقائي على النحو التالي:
عند توفّر مسارات نصية، سيظهر زر الترجمة والشرح دائمًا عند الساعة SLOT_1
.
لتغيير قيمة supportedMediaCommands
ديناميكيًا بعد بدء سياق المستلم، يمكنك استدعاء الدالة PlayerManager.setSupportedMediaCommands
لإلغاء القيمة. يمكنك أيضًا إضافة أمر جديد باستخدام addSupportedMediaCommands
أو إزالة أمر حالي باستخدام removeSupportedMediaCommands
.
تخصيص أزرار التحكم
يمكنك تخصيص عناصر التحكم باستخدام "PlayerDataBinder
". أضف الرمز التالي إلى ملف js/receiver.js
أسفل عناصر التحكم باللمس لضبط الفتحة الأولى لعناصر التحكم:
...
// 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
وخصائصها:
BrowseContent.title
BrowseContent.items
نسبة العرض إلى الارتفاع
استخدِم targetAspectRatio property
لاختيار أفضل نسبة عرض إلى ارتفاع لمواد عرض الصور. متوافقة مع ثلاث نِسَب عرض إلى ارتفاع متوافقة مع حزمة تطوير البرامج (SDK) لمعيار CAF: SQUARE_1_TO_1
وPORTRAIT_2_TO_3
وLANDSCAPE_16_TO_9
.
BrowseItem
استخدِم 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) لجهاز استقبال البث خيارًا آخر للمطوّرين يتيح لهم تصحيح الأخطاء في تطبيقات المُستلِم بسهولة من خلال استخدام CastDebugLogger API وأداة Command and Control (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
، يمكنك بسهولة تسجيل أحداث المشغّل التي تنشطها حزمة تطوير البرامج (SDK) لأداة الاستقبال المستندة إلى 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 API إنشاء رسائل السجلّ التي تظهر على سطح تصحيح أخطاء المُستلِم بألوان مختلفة. تتوفر طرق السجل التالية، مرتبة بترتيب من الأولوية القصوى إلى الأدنى:
castDebugLogger.error(custom_tag, message);
castDebugLogger.warn(custom_tag, message);
castDebugLogger.info(custom_tag, message);
castDebugLogger.debug(custom_tag, message);
بالنسبة إلى كل طريقة سجلّ، تكون المَعلمة الأولى هي علامة مخصَّصة. يمكن أن يكون هذا أي سلسلة تعريفية تجدها مفيدة. يستخدم CastDebugLogger
العلامات لفلترة السجلّات. وفي ما يلي شرح تفصيلي لاستخدام العلامات. المعلمة الثانية هي log message (الرسالة).
ل��رض السجلّات أثناء العمل، أضِف السجلّات إلى أداة اعتراض 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) لجهاز Google Cast.
ولمزيد من التفاصيل، يُرجى الاطّلاع على دليل المطوِّر حول أجهزة استقبال الويب.