1. نظرة عامة
ستتعرَّف في هذا الدرس التطبيقي على كيفية إنشاء تطبيق مخصَّص لاستقبال الويب لتشغيل المحتوى على الأجهزة التي تعمل بالبث.
ما المقصود بتكنولوجيا Google Cast؟
تسمح تكنولوجيا Google Cast للمستخدمين ببث المحتوى من جهاز جوّال إلى تلفزيون. ويمكن للمستخدمين بعد ذلك استخدام متصفّح Chrome على أجهزتهم الجوّالة أو أجهزة الكمبيوتر المكتبي كجهاز تحكّم عن بُعد لتشغيل الوسائط على التلفزيون.
تتيح حزمة تطوير البرامج (SDK) لتكنولوجيا Google Cast لتطبيقك التحكّم في الأجهزة المزوّدة بتكنولوجيا Google Cast (مثل التلفزيون أو نظام الصوت). تزودك حزمة تطوير البرامج لتكنولوجيا Cast بمكونات واجهة المستخدم اللازمة بناءً على قائمة التحقق من تصميم Google Cast.
يتم توفير قائمة التحقّق من تصميم Google Cast لجعل تجربة مستخدم Google Cast بسيطة ويمكن توقُّعها على جميع الأنظمة الأساسية المتوافقة. يمكنك الاطّلاع على مزيد من المعلومات هنا.
ما الذي سننشئه؟
عند الانتهاء من هذا الدليل التعليمي حول رموز الترميز، سيكون لديك تطبيق HTML5 يعمل كجهاز استقبال مخصّص خاص بك ويمكنه عرض محتوى الفيديو على الأجهزة المزوّدة بتقنية Cast.
المُعطيات
- كيفية إعداد جهاز الاستقبال.
- أساسيات جهاز استقبال يعمل بتكنولوجيا Google Cast استنادًا إلى "إطار عمل تطبيق Google Cast"
- كيفية استلام فيديو يتم بثّه
- كيفية دمج "مُسجِّل تصحيح الأخطاء"
- كيفية تحسين جهاز الاستقبال للتوافق مع الشاشات الذكية
المتطلبات
- أحدث إصدار من متصفّح Google Chrome
- خدمة استضافة HTTPS مثل استضافة Firebase أو ngrok
- جهاز Google Cast، مثل Chromecast أو Android TV تم ضبطه على الاتصال بالإنترنت
- تلفزيون أو شاشة مزوّدة بمنفذ إدخال HDMI.
تجربة الاستخدام
- يجب أن تكون لديك معرفة سابقة بتطوير الويب.
- ستحتاج أيضًا إلى معرفة سابقة بمشاهدة التلفزيون :)
كيف ستستخدم هذا الدليل التعليمي؟
ما مدى رضاك عن تجربتك في إنشاء تطبيقات الويب؟
كيف تقيّم تجربتك في مشاهدة التلفزيون؟
2. الحصول على نموذج الرمز
يمكنك تنزيل نموذج الرمز بالكامل على جهاز الكمبيوتر...
وفك ضغط ملف ZIP الذي تم تنزيله.
3- نشر جهاز الاستقبال على الجهاز
لتتمكن من استخدام جهاز استقبال الويب مع جهاز البث، يجب استضافته في مكان يمكن لجهاز البث الوصول إليه. إذا كان لديك خادم متاح بالفعل يتوافق مع https، فتخط التعليمات التالية ودوِّن عنوان URL، حيث ستحتاج إليه في القسم التالي.
إذا لم يكن لديك خادم متاح للاستخدام، يمكنك استخدام استضافة Firebase أو ngrok.
تشغيل الخادم
بعد إعداد الخدمة التي تريدها، انتقِل إلى app-start
وابدأ تشغيل الخادم.
دوِّن عنوان URL الخاص بالمستلِم المستضاف. ستستخدمه في القسم التالي.
4. تسجيل تطبيق في Cast Developer Console
عليك تسجيل تطبيقك لتتمكّن من تشغيل جهاز استقبال مخصّص، كما هو موضّح في هذا الدرس التطبيقي، على أجهزة Chromecast. بعد تسجيل تطبيقك، ستتلقى معرّف التطبيق الذي يجب أن يستخدمه تطبيق المرسِل لإجراء طلبات بيانات من واجهة برمجة التطبيقات، مثل تشغيل تطبيق استقبال.
انقر على "إضافة تطبيق جديد".
اختَر "مستلِم مخصّص"، وهو ما سننشئه.
أدخِل تفاصيل جهاز الاستقبال الجديد، واحرص على استخدام عنوان URL الذي حصلت عليه.
في القسم الأخير. دوِّن رقم تعريف التطبيق الذي تمّ تعيينه لجهاز الاستقبال الجديد.
عليك أيضًا تسجيل جهاز Google Cast ليتمكّن من الوصول إلى تطبيق المُستلِم قبل نشره. بعد نشر تطبيق جهاز الاستقبال، سيكون متاحًا لجميع أجهزة Google Cast. لأغراض هذا الدليل التعليمي، ننصحك بالعمل مع تطبيق مستقبل لم يتم نشره.
انقر على "إضافة جهاز جديد".
أدخِل الرقم التسلسلي المطبوع على الجهة الخلفية من جهاز البث وأضِف إليه اسمًا وصفيًا. يمكنك أيضًا العثور على رقمك التسلسلي من خلال بث محتوى شاشتك في Chrome عند الدخول إلى وحدة تحكّم المطوّرين في Google Cast SDK.
ستستغرق عملية إعداد الجهاز والمُستلِم للاختبار من 5 إلى 15 دقيقة. بعد الانتظار من 5 إلى 15 دقيقة، يجب إعادة تشغيل جهاز البث.
5- تشغيل نموذج التطبيق
بينما ننتظر حتى يكون تطبيق الاستقبال الجديد جاهزًا للاختبار، دعنا نتعرف على نموذج تطبيق مستلم مكتمل. سيتمكن جهاز الاستقبال الذي سننشئه من تشغيل الوسائط باستخدام بث معدل نقل البيانات التكيُّفي (سنستخدم نموذج محتوى مرمّز للبث الديناميكي التكيُّفي عبر HTTP (DASH)).
في المتصفّح، افتح أداة التحكّم والتوجيه (CaC).
- من المفترض أن تظهر لك "أداة ربط الحسابات".
- استخدام الخيار التلقائي "CC1AD845" نموذج رقم تعريف المتلقي وانقر على "تعيين رقم تعريف التطبيق" .
- انقر على زر البث في أعلى يمين الشاشة واختَر جهاز Google Cast.
- انتقِل إلى علامة التبويب "تحميل الوسائط" في أعلى الصفحة.
- انقر على الزر "التحميل حسب المحتوى" لتشغيل عيّنة فيديو.
- سيبدأ تشغيل الفيديو على جهاز Google Cast لعرض وظائف جهاز الاستقبال الأساسية باستخدام "جهاز الاستقبال التلقائي".
6- تجهيز مشروع البدء
نحتاج إلى إتاحة استخدام Google Cast في تطبيق البدء الذي نزّلته. في ما يلي بعض المصطلحات المتعلّقة بخدمة Google Cast التي سنستخدمها في هذا الدليل التعليمي حول البرمجة:
- تطبيق مُرسِل يعمل على جهاز جوّال أو كمبيوتر محمول
- تطبيق استقبال يعمل على جهاز Google Cast
أنت الآن جاهز لتطوير المشروع الأساسي باستخدام محرِّر النصوص المفضّل لديك:
- اختَر الدليل
app-start
من تنزيل نموذج الرمز. - فتح
js/receiver.js
وindex.html
يُرجى العلم أنّه أثناء العمل على هذا الدرس التطبيقي حول الترميز، من المفترض أن ينفّذ "http-server
" التغييرات التي تجريها. إذا لاحظت أنّه لا يعمل، حاوِل إغلاق http-server
وإعادة تشغيله.
تصميم التطبيق
يُنشئ تطبيق المُستلِم جلسة البث وسيظل في وضع الاستعداد إلى أن يصل طلب LOAD (بمعنى آخر، الأمر بتشغيل قطعة من الوسائط) من المُرسِل.
ويتكون التطبيق من طريقة عرض رئيسية واحدة تم تحديدها في index.html
وملف JavaScript واحد باسم js/receiver.js
يحتوي على كل الإجراءات المنطقية لجعل المستلِم يعمل.
index.html
سيحتوي ملف html هذا على واجهة المستخدم لتطبيق المُستلِم. وهو فارغ في الوقت الحالي، وسنضيف إليه المزيد من خلال ورشة رموز التطبيقات.
receiver.js
سيدير هذا النص المنطقي كله في تطبيق الاستقبال. أصبح هذا الملف في الوقت الحالي مجرّد ملف فارغ، لكننا سنحوّله إلى مستقبِل Cast يعمل بشكل كامل مع بضعة أسطر من الرموز في القسم التالي.
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>
أضِف الرمز التالي إلى <body>
index.html
قبل <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
من حزمة تطوير البرامج (SDK) لتطبيق Cast الذي يمثّل عنصر وسائط. - يتصل المُرسِل بجهاز البث لتشغيل تطبيق المُستلِم.
- يحمّل المستلِم عنصر
MediaInfo
من خلال طلبLOAD
لتشغيل المحتوى. - يراقب جهاز الاستقبال حالة الوسائط ويتتبّعها.
- يرسل المُرسِل أوامر التشغيل إلى المُستلِم للتحكّم في التشغيل استنادًا إلى تفاعلات المستخدم مع تطبيق المُرسِل.
في هذه المحاولة الأساسية الأولى، ستتم تعبئة MediaInfo
بعنوان URL لمادة عرض قابلة للتشغيل (مخزنة في MediaInfo.contentUrl
).
يستخدم المُرسِل الفعلي معرّف وسائط خاصًا بالتطبيق في MediaInfo.contentId
. يستخدم المستلِم contentId
كمعرّف لإجراء طلبات البيانات المناسبة لواجهة برمجة التطبيقات في الخلفية لتحديد عنوان URL الفعلي للمادة وضبطه على MediaInfo.contentUrl.
. سيتولّى المستلِم أيضًا مهامًا مثل الحصول على ترخيص إدارة الحقوق الرقمية أو إدراج معلومات عن الفواصل الإعلانية.
سنوسّع نطاق جهاز الاستقبال لإجراء إجراء مماثل في القسم التالي. في الوقت الحالي، انقر على رمز البث واختَر جهازك لفتح جهاز الاستقبال.
الانتقال إلى "Load Media" (تحميل الوسائط) وانقر على "التحميل حسب المحتوى" . من المفترض أن يبدأ المستلِم في تشغيل عيّنة المحتوى.
لذا، فإنّ معالجات حزمة تطوير البرامج (SDK) للمستلِمين جاهزة لإعداد ما يلي:
- جارٍ إعداد جلسة البث
- معالجة طلبات
LOAD
الواردة من المُرسِلين التي تحتوي على مواد عرض قابلة للتشغيل - توفير واجهة مستخدم أساسية للمشغّل جاهزة للعرض على الشاشة الكبيرة.
يمكنك استكشاف "أداة ربط المحتوى" ورمزها قبل الانتقال إلى القسم التالي، حيث سنوسّع نطاق المستلِم للتواصل مع نموذج بسيط لواجهة برمجة التطبيقات من أجل تلبية طلبات 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
.
اعتراض طلب 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.
استخدام واجهة برمجة التطبيقات Sample API لمحتوى DASH
الآن وبعد أن نكون قد أعددنا اعتراض التحميل، سنحدد نوع المحتوى للمستلم. ستوفّر هذه المعلومات للمستلِم عنوان URL لقائمة التشغيل الرئيسية ونوع MIME للبث. أضِف الرمز التالي إلى ملف js/receiver.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';
...
}
});
});
});
بعد إكمال هذه الخطوة، يمكنك المتابعة إلى Testing It Out لمحاولة تحميل محتوى DASH. إذا أردت اختبار التحميل باستخدام محتوى HLS بدلاً من ذلك، اطّلِع على الخطوة التالية.
استخدام محتوى HLS في Sample API
يتضمّن نموذج واجهة برمجة التطبيقات محتوى HLS بالإضافة إلى DASH. بالإضافة إلى ضبط contentType
كما فعلنا في الخطوة السابقة، سيحتاج طلب التحميل إلى بعض السمات الإضافية لكي يستخدم نموذج عناوين URL لبروتوكول HLS في واجهة برمجة التطبيقات. عند ضبط الجهاز المُستلِم على تشغيل مجموعات بث HLS، يكون نوع الحاوية التلقائي المتوقَّع هو بث النقل (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) واضبط رقم تعريف تطبيقك على رقم تعريف تطبيق جهاز الاستقبال. حدد جهازك باستخدام زر البث.
الانتقال إلى "Load Media" (تحميل الوسائط) . هذه المرة احذف النص في "عنوان 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
، سيتم عرض تنسيق التحكّم التلقائي على النحو التالي:
عندما تكون قيمة supportedMediaCommands مساوية 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 Receiver تتيح للمستخدمين استكشاف محتوى إضافي على الأجهزة التي تعمل باللمس. لتنفيذ هذا الإجراء، يمكنك استخدام 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. تصحيح أخطاء تطبيقات المُستلِم
توفّر حزمة تطوير البرامج لجهاز الاستقبال خيارًا آخر للمطوّرين يمكنهم بسهولة تصحيح أخطاء تطبيقات الاستقبال باستخدام CastDebugLogger API وأداة الأوامر والتحكّم (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 Receiver واستخدام مستويات مختلفة لتسجيل البيانات لتسجيل بيانات الأحداث. تستخدم إعدادات 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.
لمزيد من التفاصيل، يُرجى الاطّلاع على دليل مطوّري Web Receiver.