1- نظرة عامة
يشرح لك هذا الدرس التطبيقي حول الترميز كيفية تعديل تطبيق فيديو حالي على الويب لبث المحتوى على جهاز يعمل بتكنولوجيا Google Cast.
ما هي تكنولوجيا Google Cast؟
تتيح تكنولوجيا Google Cast للمستخدمين بث المحتوى من جهاز جوّال إلى تلفزيون. ويمكن للمستخدمين بعد ذلك استخدام أجهزتهم الجوّالة كوحدة تحكّم عن بُعد لتشغيل الوسائط على التلفزيون.
تتيح لك حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast توسيع نطاق تطبيقك للتحكّم في التلفزيون أو نظام الصوت. تتيح لك حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast إضافة مكوّنات واجهة المستخدم اللازمة بناءً على قائمة التحقق من تصميم Google Cast.
تتوفر قائمة التحقق من تصميم Google Cast لتسهيل تجربة مستخدم البث على جميع الأنظمة الأساسية المتوافقة.
ماذا سنبني؟
عند الانتهاء من هذا الدرس التطبيقي حول الترميز، يتوفر لديك تطبيق فيديو ويب Chrome يتيح بث الفيديوهات على جهاز Google Cast.
ما ستتعرَّف عليه
- كيفية إضافة حزمة تطوير البرامج (SDK) لتقنية Google Cast إلى نموذج تطبيق فيديو
- كيفية إضافة زر البث لاختيار جهاز Google Cast
- كيفية الاتصال بجهاز بث وتشغيل جهاز استقبال الوسائط.
- كيفية بث فيديو
- كيفية دمج Cast Connect
المتطلبات
- أحدث إصدار من متصفِّح Google Chrome.
- خدمة استضافة HTTPS، مثل استضافة Firebase أو ngrok
- جهاز Google Cast، مثل Chromecast أو Android TV تم إعداده للوصول إلى الإنترنت
- تلفزيون أو شاشة مزوّدة بمنفذ إدخال HDMI
- يجب توفُّر جهاز "Chromecast مع Google TV" لاختبار دمج Cast Connect، ولكنّه اختياري في بقية الدرس التطبيقي حول الترميز. إذا لم يكن لديك أحد هذه الأجهزة، يمكنك تخطي خطوة إضافة دعم Cast Connect في نهاية هذا البرنامج التعليمي.
التجربة
- يجب أن تكون لديك معرفة سابقة بتطوير الويب.
- ستحتاج أيضًا إلى المعرفة السابقة بمشاهدة التلفزيون :)
كيف ستستخدم هذا البرنامج التعليمي؟
ما هو تقييمك لتجربتك في إنشاء تطبيقات الويب؟
ما هو تقييمك لتجربتك في مشاهدة التلفزيون؟
2. الحصول على الرمز النموذجي
يمكنك تنزيل الرمز النموذجي بالكامل على جهاز الكمبيوتر...
وفك ضغط ملف zip الذي تم تنزيله.
3. تشغيل نموذج التطبيق
أولاً، لنرى كيف يبدو نموذج التطبيق المكتمل. التطبيق عبارة عن مشغّل فيديو أساسي. ويمكن للمستخدم اختيار فيديو من قائمة ثم تشغيله على الجهاز على الجهاز أو بثّه على جهاز Google Cast.
يجب استضافتك لنتمكّن من استخدام المحتوى المكتمل.
إذا لم يكن لديك خادم متاح للاستخدام، يمكنك استخدام استضافة Firebase أو ngrok.
تشغيل الخادم
بعد إعداد الخدمة من اختيارك، انتقِل إلى app-done
وابدأ تشغيل الخادم.
في المتصفح، انتقل إلى عنوان URL https الخاص بالنموذج الذي استضافته.
- من المفترض أن يظهر لك تطبيق الفيديو.
- انقر على زر البث واختَر جهاز Google Cast.
- اختَر فيديو، وانقر على زر التشغيل.
- سيبدأ تشغيل الفيديو على جهاز Google Cast.
انقر على زر الإيقاف المؤقت داخل عنصر الفيديو لإيقاف الفيديو مؤقتًا على جهاز الاستقبال. انقر على زر التشغيل في عنصر الفيديو لمواصلة تشغيل الفيديو مرة أخرى.
انقر على زر البث لإيقاف البث إلى جهاز Google Cast.
قبل أن نمضي قدمًا، أوقف الخادم.
4. تجهيز مشروع بدء المشروع
نحتاج إلى توفير الدعم لتقنية Google Cast إلى التطبيق للبدء الذي نزّلته. إليك بعض مصطلحات Google Cast التي سنستخدمها في هذا الدرس التطبيقي حول الترميز:
- تشغيل تطبيق المُرسِل على جهاز جوّال أو كمبيوتر محمول
- يتم تشغيل تطبيق جهاز استقبال على جهاز Google Cast.
أنت الآن جاهز للبناء على مشروع المبتدئين باستخدام محرر النصوص المفضل لديك:
- اختَر الدليل
app-start
من عملية تنزيل الرمز النموذجي. - شغِّل التطبيق باستخدام الخادم واستكشف واجهة المستخدم.
ملاحظة: أثناء العمل على هذا الدرس التطبيقي حول الترميز، عليك إعادة استضافة النموذج على الخادم استنادًا إلى الخدمة.
تصميم التطبيقات
يجلب التطبيق قائمة فيديوهات من خادم ويب بعيد ويقدّم قائمة يمكن للمستخدم تصفّحها. ويمكن للمستخدمين اختيار فيديو للاطّلاع على التفاصيل أو تشغيله محليًا على الجهاز الجوّال.
يتكون التطبيق من عرض رئيسي واحد، محدد في index.html
، ووحدة التحكم الرئيسية، CastVideos.js.
index.html
يعرّف ملف html هذا تقريبًا جميع واجهة المستخدم لتطبيق الويب.
هناك بضعة أقسام من المشاهدات، لدينا علامة div#main_video
التي تحتوي على عنصر الفيديو. في ما يتعلق بـ "مقطع الفيديو"، لدينا div#media_control
، التي تحدد جميع عناصر التحكم في عنصر الفيديو. أسفل ذلك، يظهر media_info
الذي يعرض تفاصيل الفيديو قيد العرض. أخيرًا، يعرض القسم carousel
قائمة فيديوهات في قسم div.
يعمل ملف index.html
أيضًا على تثبيت حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast، ويطلب من الدالة CastVideos
التحميل.
يتم تحديد معظم المحتوى الذي سيقوم بتعبئة هذه العناصر وإدخاله والتحكم فيه في CastVideos.js
. لذا، دعونا نلقِ نظرة على ذلك.
CastVideos.js
يدير هذا النص البرمجي كل العمليات المنطقية لتطبيق YouTube Cast على الويب. إنّ قائمة الفيديوهات والبيانات الوصفية المرتبطة بها والمحدّدة في CastVideos.js
مضمَّنة في عنصر باسم mediaJSON
.
هناك بعض الأقسام الرئيسية المسؤولة عن إدارة الفيديو وتشغيله محليًا وعن بُعد. بشكل عام، يعد هذا تطبيق ويب مباشرًا إلى حد ما.
CastPlayer
هي الفئة الرئيسية التي تدير التطبيق بالكامل وتتولى إعداد المشغّل واختيار الوسائط وربط الأحداث بخدمة PlayerHandler
لتشغيل الوسائط. CastPlayer.prototype.initializeCastPlayer
هي الطريقة التي تضبط بها جميع وظائف البث. يعمل تطبيق CastPlayer.prototype.switchPlayer
على تبديل الحالة بين المشغّلات المحلية ومشغّلات التحكّم عن بُعد. يتيح CastPlayer.prototype.setupLocalPlayer
وCastPlayer.prototype.setupRemotePlayer
إمكانية تشغيل المشغّلات المحلية والبعيدة.
PlayerHandler
هو الصف المسؤول عن إدارة تشغيل الوسائط. هناك عدد من الطرق الأخرى المسؤولة عن تفاصيل إدارة الوسائط والتشغيل.
الأسئلة الشائعة
5. إضافة زر البث
يعرض التطبيق الذي يعمل بتكنولوجيا Google Cast زر البث في عنصر الفيديو. يؤدي النقر على الزر "بث" إلى عرض قائمة بأجهزة البث التي يمكن للمستخدم اختيارها. إذا كان المستخدم يشغِّل المحتوى محليًا على جهاز المُرسِل، سيؤدي اختيار جهاز بث إلى بدء التشغيل أو استئنافه على جهاز البث هذا. يمكن للمستخدم في أي وقت أثناء جلسة البث النقر على زر البث وإيقاف بث تطبيقك على جهاز البث. يجب أن يكون المستخدم قادرًا على الاتصال بجهاز البث أو قطع الاتصال به أثناء استخدام أي شاشة من التطبيق، كما هو موضح في قائمة تحقق تصميم Google Cast.
الإعدادات
يتطلب مشروع بدء المشروع الاعتماديات والإعداد نفسهما كما فعلت في نموذج التطبيق المكتمل، ولكن في هذه المرة، تستضيف محتوى app-start
.
في المتصفّح، انتقِل إلى عنوان URL لـ https
الخاص بالنموذج الذي استضافته.
تذكَّر أنّه أثناء إجراء التغييرات، عليك إعادة استضافة العيّنة على الخادم بناءً على الخدمة.
الإعداد
يتضمن إطار عمل Cast عنصرًا عالميًا مفردًا، وهو CastContext
، الذي ينسق جميع أنشطة إطار العمل. يجب إعداد هذا الكائن في بداية مراحل نشاط التطبيق، ويتم استدعاؤه عادةً من استدعاء مخصّص إلى window['__onGCastApiAvailable']
، والذي يتم استدعاؤه بعد تحميل حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast، ويكون متاحًا للاستخدام. في هذه الحالة، يتم استدعاء CastContext
باللغة CastPlayer.prototype.initializeCastPlayer
، والتي يتم استدعاؤها من معاودة الاتصال المذكورة أعلاه.
يجب تقديم كائن options
JSON عند إعداد CastContext
. تحتوي هذه الفئة على خيارات تؤثر في سلوك إطار العمل. وأهم هذه المعلومات هو معرّف تطبيق المُستلِم الذي يُستخدم لفلترة قائمة أجهزة البث المتاحة لعرض الأجهزة القادرة على تشغيل التطبيق المحدّد فقط وتشغيل تطبيق جهاز الاستقبال عند بدء جلسة البث.
عندما تطوِّر تطبيقك الذي يعمل بتكنولوجيا Google Cast، عليك التسجيل كمطوّر برامج Cast ثم الحصول على معرّف التطبيق لتطبيقك. وسنستخدم في هذا الدرس التطبيقي حول الترميز نموذج رقم تعريف تطبيق.
أضِف الرمز التالي إلى index.html
في نهاية القسم body
:
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
أضِف الرمز التالي إلى index.html
لإعداد تطبيق CastVideos
، وكذلك لإعداد CastContext
:
<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
castPlayer.initializeCastPlayer();
}
};
</script>
والآن، نحتاج إلى إضافة طريقة جديدة في CastVideos.js
تتوافق مع الطريقة التي استدعيناها للتو في index.html
. دعونا نضيف طريقة جديدة تُسمى initializeCastPlayer
تحدد خيارات على CastContext وتهيئ RemotePlayer
وRemotePlayerControllers
الجديدتين:
/**
* This method sets up the CastContext, and a few other members
* that are necessary to play and control videos on a Cast
* device.
*/
CastPlayer.prototype.initializeCastPlayer = function() {
var options = {};
// Set the receiver application ID to your own (created in
// the Google Cast Developer Console), or optionally
// use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
options.receiverApplicationId = 'C0868879';
// Auto join policy can be one of the following three:
// ORIGIN_SCOPED - Auto connect from same appId and page origin
// TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
// PAGE_SCOPED - No auto connect
options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
cast.framework.CastContext.getInstance().setOptions(options);
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
this.switchPlayer.bind(this)
);
};
أخيرًا، نحتاج إلى إنشاء المتغيّرات RemotePlayer
وRemotePlayerController
:
var CastPlayer = function() {
//...
/* Cast player variables */
/** @type {cast.framework.RemotePlayer} */
this.remotePlayer = null;
/** @type {cast.framework.RemotePlayerController} */
this.remotePlayerController = null;
//...
};
زر الإرسال
الآن وبعد إعداد CastContext
، نحتاج إلى إضافة زر البث للسماح للمستخدم باختيار جهاز بث. توفر حزمة تطوير البرامج (SDK) لجهاز Cast مكوّن زر بث يُسمى google-cast-launcher
بمعرّف "castbutton"
. ويمكن إضافته إلى عنصر الفيديو في التطبيق عن طريق إضافة button
في القسم media_control
.
هذا هو الشكل الذي سيبدو عليه عنصر الزر:
<google-cast-launcher id="castbutton"></google-cast-launcher>
أضِف الرمز التالي إلى index.html
في القسم media_control
:
<div id="media_control">
<div id="play"></div>
<div id="pause"></div>
<div id="progress_bg"></div>
<div id="progress"></div>
<div id="progress_indicator"></div>
<div id="fullscreen_expand"></div>
<div id="fullscreen_collapse"></div>
<google-cast-launcher id="castbutton"></google-cast-launcher>
<div id="audio_bg"></div>
<div id="audio_bg_track"></div>
<div id="audio_indicator"></div>
<div id="audio_bg_level"></div>
<div id="audio_on"></div>
<div id="audio_off"></div>
<div id="duration">00:00:00</div>
</div>
يمكنك الآن إعادة تحميل الصفحة في متصفّح Chrome. من المفترض أن يظهر لك زر البث في عنصر الفيديو، وعندما تنقر عليه، سيظهر لك أجهزة البث على شبكتك المحلية. تتم إدارة ميزة "اكتشاف الأجهزة" تلقائيًا من خلال متصفّح Chrome. اختَر جهاز البث وسيتم تحميل نموذج تطبيق الاستقبال على جهاز البث.
لم نقم بتوفير أي دعم لتشغيل الوسائط، لذا لن تتمكن من تشغيل الفيديوهات على جهاز البث حتى الآن. انقر على زر البث لإيقاف البث.
6. بث محتوى الفيديو
وسيتم توسيع نطاق نموذج التطبيق لتشغيل الفيديوهات أيضًا عن بُعد على جهاز بث. لتنفيذ ذلك، نحتاج إلى الاستماع إلى الأحداث المختلفة التي تم إنشاؤها بواسطة إطار عمل Cast.
بث الوسائط
إذا أردت تشغيل وسائط على جهاز بث، يجب إجراء ما يلي:
- يمكنك إنشاء عنصر
MediaInfo
JSON
من حزمة تطوير البرامج (SDK) للإرسال والذي ينشئ نموذجًا لعنصر وسائط. - يتصل المستخدم بجهاز البث لتشغيل تطبيق جهاز الاستقبال.
- عليك تحميل الكائن
MediaInfo
في جهاز الاستقبال وتشغيل المحتوى. - تتبُّع حالة الوسائط
- إرسال أوامر التشغيل إلى المتلقي بناءً على تفاعلات المستخدم.
تتمثل الخطوة الأولى في ربط عنصر بعنصر آخر، ويعني ذلك أنّ السمة MediaInfo
تفهمها حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast، وmediaJSON
هو المكوّن الإضافي في تطبيقنا لعنصر وسائط، ويمكننا بسهولة ربط mediaJSON
بعنصر MediaInfo
. لقد انتهينا من الخطوة 2 في القسم السابق. من السهل تنفيذ الخطوة الثالثة باستخدام حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast.
يفرّق نموذج التطبيق CastPlayer
بين التشغيل المحلي والتشغيل عن بُعد باستخدام طريقة switchPlayer
:
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
//...
ليس من المهم في هذا الدرس التطبيقي حول الترميز أن تفهم بالضبط آلية عمل نموذج مشغّل الفيديو المنطقي. ومع ذلك، من المهم أن تدرك أنه يجب تعديل مشغّل الوسائط في تطبيقك ليكون على دراية بكل من التشغيل المحلي وعن بُعد.
في الوقت الحالي، يكون المشغّل المحلي في حالة التشغيل المحلي دائمًا لأنّه لا يعرف أي شيء عن حالات البثّ. نحتاج إلى تحديث واجهة المستخدم بناءً على انتقالات الحالة التي تحدث في إطار عمل Cast. على سبيل المثال، إذا بدأنا بث المحتوى، يجب إيقاف التشغيل المحلي وإيقاف بعض عناصر التحكّم. وبالمثل، إذا أوقفنا البث عندما نكون في وحدة التحكّم في طريقة العرض هذه، يجب أن ننتقل إلى التشغيل على الجهاز. لحلّ المشكلة، نحتاج إلى الاستماع إلى الأحداث المختلفة الناتجة عن إطار عمل Cast.
إدارة جلسة البث
بالنسبة إلى إطار عمل البث، تجمع جلسة البث بين خطوات الاتصال بجهاز وبدء تشغيل (أو الانضمام إلى جلسة حالية) والتوصيل بتطبيق مستقبِل وإعداد قناة تحكّم في الوسائط إذا كان ذلك مناسبًا. قناة التحكم في الوسائط هي الطريقة التي يرسل بها إطار عمل البث ويتلقى الرسائل المتعلقة بتشغيل الوسائط من جهاز الاستقبال.
ستبدأ جلسة البث تلقائيًا عندما يختار المستخدم جهازًا من زر البث، وستتوقّف تلقائيًا عند إلغاء اتصال المستخدم. يتم أيضًا التعامل تلقائيًا مع إعادة الاتصال بجلسة جهاز الاستقبال بسبب مشاكل في الشبكة من خلال إطار عمل البث.
تتم إدارة جلسات البث من خلال جهاز CastSession
، والذي يمكن الوصول إليه عبر cast.framework.CastContext.getInstance().getCurrentSession()
. يمكن استخدام استدعاءات EventListener
لمراقبة أحداث الجلسات، مثل إنشائها وتعليقها واستئنافها وإنهائها.
في تطبيقنا الحالي، يتم التعامل مع جميع عمليات إدارة الجلسات والحالة نيابةً عنا بطريقة setupRemotePlayer
. لنبدأ ضبط هذا الإجراء في تطبيقك من خلال إضافة الرمز التالي إلى CastVideos.js
:
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
this.playerHandler.setTarget(playerTarget);
// Setup remote player volume right on setup
// The remote player may have had a volume set from previous playback
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
}
var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = currentVolume + 'px';
p.style.marginTop = -currentVolume + 'px';
this.hideFullscreenButton();
this.playerHandler.play();
};
ما زلنا بحاجة إلى ربط جميع الأحداث من عمليات معاودة الاتصال والتعامل مع جميع الأحداث القادمة. هذا أمر بسيط إلى حد ما، لذلك دعنا نهتم به الآن:
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
// Add event listeners for player changes which may occur outside sender app
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function() {
if (this.remotePlayer.isPaused) {
this.playerHandler.pause();
} else {
this.playerHandler.play();
}
}.bind(this)
);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
function() {
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
} else {
this.playerHandler.unMute();
}
}.bind(this)
);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
function() {
var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = newVolume + 'px';
p.style.marginTop = -newVolume + 'px';
}.bind(this)
);
// This object will implement PlayerHandler callbacks with
// remotePlayerController, and makes necessary UI updates specific
// to remote playback
var playerTarget = {};
playerTarget.play = function () {
if (this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
var vi = document.getElementById('video_image');
vi.style.display = 'block';
var localPlayer = document.getElementById('video_element');
localPlayer.style.display = 'none';
}.bind(this);
playerTarget.pause = function () {
if (!this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
}.bind(this);
playerTarget.stop = function () {
this.remotePlayerController.stop();
}.bind(this);
playerTarget.getCurrentMediaTime = function() {
return this.remotePlayer.currentTime;
}.bind(this);
playerTarget.getMediaDuration = function() {
return this.remotePlayer.duration;
}.bind(this);
playerTarget.updateDisplayMessage = function () {
document.getElementById('playerstate').style.display = 'block';
document.getElementById('playerstatebg').style.display = 'block';
document.getElementById('video_image_overlay').style.display = 'block';
document.getElementById('playerstate').innerHTML =
this.mediaContents[ this.currentMediaIndex]['title'] + ' ' +
this.playerState + ' on ' + castSession.getCastDevice().friendlyName;
}.bind(this);
playerTarget.setVolume = function (volumeSliderPosition) {
// Add resistance to avoid loud volume
var currentVolume = this.remotePlayer.volumeLevel;
var p = document.getElementById('audio_bg_level');
if (volumeSliderPosition < FULL_VOLUME_HEIGHT) {
var vScale = this.currentVolume * FULL_VOLUME_HEIGHT;
if (volumeSliderPosition > vScale) {
volumeSliderPosition = vScale + (pos - vScale) / 2;
}
p.style.height = volumeSliderPosition + 'px';
p.style.marginTop = -volumeSliderPosition + 'px';
currentVolume = volumeSliderPosition / FULL_VOLUME_HEIGHT;
} else {
currentVolume = 1;
}
this.remotePlayer.volumeLevel = currentVolume;
this.remotePlayerController.setVolumeLevel();
}.bind(this);
playerTarget.mute = function () {
if (!this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.unMute = function () {
if (this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.isMuted = function() {
return this.remotePlayer.isMuted;
}.bind(this);
playerTarget.seekTo = function (time) {
this.remotePlayer.currentTime = time;
this.remotePlayerController.seek();
}.bind(this);
this.playerHandler.setTarget(playerTarget);
// Setup remote player volume right on setup
// The remote player may have had a volume set from previous playback
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
}
var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = currentVolume + 'px';
p.style.marginTop = -currentVolume + 'px';
this.hideFullscreenButton();
this.playerHandler.play();
};
جارٍ تحميل الوسائط
في حزمة تطوير البرامج (SDK) الخاصة بتكنولوجيا Google Cast، يوفِّر كل من RemotePlayer
وRemotePlayerController
مجموعة من واجهات برمجة التطبيقات المناسبة لإدارة تشغيل الوسائط عن بُعد على جهاز الاستقبال. بالنسبة إلى CastSession
الذي يتيح تشغيل الوسائط، سيتم إنشاء مثيلَي RemotePlayer
وRemotePlayerController
تلقائيًا بواسطة حزمة تطوير البرامج (SDK). ويمكنك الوصول إليها من خلال إنشاء مثيلين cast.framework.RemotePlayer
وcast.framework.RemotePlayerController
على التوالي، كما هو موضّح سابقًا في الدرس التطبيقي حول الترميز.
بعد ذلك، نحتاج إلى تحميل الفيديو المحدّد حاليًا على المُستلِم من خلال إنشاء عنصر MediaInfo كي تتمكّن حزمة تطوير البرامج (SDK) من معالجة الطلب وتمريره. أضِف الرمز التالي إلى setupRemotePlayer
لتنفيذ ذلك:
/**
* Set the PlayerHandler target to use the remote player
*/
CastPlayer.prototype.setupRemotePlayer = function () {
//...
playerTarget.load = function (mediaIndex) {
console.log('Loading...' + this.mediaContents[mediaIndex]['title']);
var mediaInfo = new chrome.cast.media.MediaInfo(
this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];
mediaInfo.metadata.images = [
{'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
this.playerHandler.loaded.bind(this.playerHandler),
function (errorCode) {
this.playerState = PLAYER_STATE.ERROR;
console.log('Remote media load error: ' +
CastPlayer.getErrorMessage(errorCode));
}.bind(this));
}.bind(this);
//...
};
أضف الآن طريقة للتبديل بين التشغيل المحلي والتشغيل عن بُعد:
/**
* This is a method for switching between the local and remote
* players. If the local player is selected, setupLocalPlayer()
* is run. If there is a cast device connected we run
* setupRemotePlayer().
*/
CastPlayer.prototype.switchPlayer = function() {
this.stopProgressTimer();
this.resetVolumeSlider();
this.playerHandler.stop();
this.playerState = PLAYER_STATE.IDLE;
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
this.setupRemotePlayer();
return;
}
}
this.setupLocalPlayer();
};
أخيرًا، أضِف طريقة لمعالجة أي رسائل خطأ في البث:
/**
* Makes human-readable message from chrome.cast.Error
* @param {chrome.cast.Error} error
* @return {string} error message
*/
CastPlayer.getErrorMessage = function(error) {
switch (error.code) {
case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
return 'The API is not initialized.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CANCEL:
return 'The operation was canceled by the user' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CHANNEL_ERROR:
return 'A channel to the receiver is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.EXTENSION_MISSING:
return 'The Cast extension is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.INVALID_PARAMETER:
return 'The parameters to the operation were not valid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
return 'No receiver was compatible with the session request.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.SESSION_ERROR:
return 'A session could not be created, or a session was invalid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.TIMEOUT:
return 'The operation timed out.' +
(error.description ? ' :' + error.description : '');
}
};
يمكنك الآن تشغيل التطبيق والاتصال بجهاز البث وبدء تشغيل فيديو. من المفترض أن يظهر لك الفيديو الذي يتم تشغيله على جهاز الاستقبال.
7. إضافة دعم Cast Connect
تسمح مكتبة Cast Connect لتطبيقات المرسل الحالية بالاتصال بتطبيقات Android TV عبر بروتوكول البث. يعتمد Cast Connect على البنية الأساسية للبث، حيث يعمل تطبيق Android TV كمستلم.
التبعيات
- الإصدار M87 من متصفّح Chrome أو إصدار أحدث
مجموعة متوافقة مع جهاز استقبال Android
لتشغيل تطبيق Android TV، الذي يُشار إليه أيضًا باسم Android Receiver، يجب ضبط علامة androidReceiverCompatible
على true في الكائن CastOptions
.
أضِف الرمز التالي إلى CastVideos.js
في دالة initializeCastPlayer
:
var options = {};
...
options.androidReceiverCompatible = true;
cast.framework.CastContext.getInstance().setOptions(options);
ضبط بيانات اعتماد الإطلاق
على جانب المُرسِل، يمكنك تحديد CredentialsData
لتمثيل المنضمّ إلى الجلسة. وcredentials
هي سلسلة يمكن أن يحدّدها المستخدم، ما دام بإمكان تطبيق ATV التعرّف عليها. لا يتم تمرير CredentialsData
إلى تطبيق Android TV إلا أثناء وقت التشغيل أو الانضمام. وإذا أعددته مرة أخرى أثناء الاتصال، لن يتم تمريره إلى تطبيق Android TV.
لضبط بيانات اعتماد التشغيل، يجب تحديد CredentialsData
في أي وقت بعد ضبط خيارات الإطلاق.
أضِف الرمز التالي إلى صف "CastVideos.js
" ضمن الدالة initializeCastPlayer
:
cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...
ضبط بيانات الاعتماد عند طلب التحميل
إذا كان تطبيقا Web Receiver (جهاز استقبال الويب) وتطبيق Android TV يتعاملان مع credentials
بشكل مختلف، قد تحتاج إلى تحديد بيانات اعتماد منفصلة لكل منهما. لحل هذه المشكلة، أضِف الرمز التالي في CastVideos.js
ضمن playerTarget.load
في دالة setupRemotePlayer
:
...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...
استنادًا إلى تطبيق المُستلِم الذي يتم إرسال الرسائل إليه، ستتولى حزمة تطوير البرامج (SDK) الآن تلقائيًا معالجة بيانات الاعتماد التي يجب استخدامها في الجلسة الحالية.
اختبار Cast Connect
خطوات تثبيت Android TV APK على جهاز "Chromecast مع Google TV":
- ابحث عن عنوان IP لجهاز Android TV. يتوفر هذا الخيار عادةً ضمن الإعدادات > الشبكة والإنترنت > (اسم الشبكة التي يتصل بها جهازك). على يسار الشاشة، سيتم عرض التفاصيل وعنوان IP لجهازك على الشبكة.
- استخدِم عنوان IP لجهازك للاتصال به عبر ADB باستخدام الوحدة الطرفية:
$ adb connect <device_ip_address>:5555
- من النافذة الطرفية، انتقِل إلى مجلد المستوى الأعلى لنماذج الدرس التطبيقي حول الترميز الذي نزّلته في بداية هذا الدرس التطبيقي حول الترميز. مثلاً:
$ cd Desktop/chrome_codelab_src
- ثبِّت ملف AP .في هذا المجلد على Android TV عن طريق تشغيل:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- من المفترض أن تتمكّن الآن من الاطّلاع على تطبيق باسم بث الفيديوهات في قائمة تطبيقاتك على جهاز Android TV.
- شغِّل رمز المُرسِل المحدَّث على الويب وأنشِئ جلسة بث من خلال جهاز Android TV باستخدام رمز البث أو اختَر
Cast..
من القائمة المنسدلة في متصفّح Chrome. من المفترض أن يؤدي هذا الإجراء الآن إلى تشغيل تطبيق Android TV على جهاز الاستقبال الذي يعمل بنظام التشغيل Android والوصول إلى إمكانية التحكّم في التشغيل باستخدام جهاز التحكّم بـ Android TV عن بُعد.
8. تهانينا
تعرف الآن كيفية تفعيل تطبيق فيديو Cast باستخدام تطبيقات Cast SDK على تطبيق Chrome على الويب.
ولمزيد من التفاصيل، يُرجى الاطّلاع على دليل مطوِّر Web Sender.