1. نظرة عامة
سيعلمك هذا الدليل التعليمي كيفية تعديل تطبيق فيديو على الويب حالي لبث المحتوى على جهاز مزوّد بتكنولوجيا Google Cast.
ما هي تكنولوجيا Google Cast؟
تسمح تكنولوجيا Google Cast للمستخدمين ببث المحتوى من جهاز جوّال إلى تلفزيون. ويمكن للمستخدمين بعد ذلك استخدام أجهزتهم الجوّالة كجهاز تحكّم عن بُعد لتشغيل الوسائط على التلفزيون.
تتيح لك حزمة تطوير البرامج (SDK) لتكنولوجيا Google Cast إمكانية توسيع نطاق تطبيقك للتحكم في التلفزيون أو نظام الصوت. تسمح لك حزمة تطوير البرامج (SDK) لتكنولوجيا Cast بإضافة مكونات واجهة المستخدم اللازمة بناءً على قائمة التحقق من تصميم Google Cast.
يتم توفير قائمة التحقّق من تصميم Google Cast لجعل تجربة استخدام 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، ولكنّه اختياري لبقية خطوات Codelab. إذا لم يكن لديك حساب، يمكنك تخطّي خطوة إضافة ميزة 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
التي تعرض تفاصيل الفيديو المعروض. أخيرًا، يعرض div carousel
قائمة بالفيديوهات في div.
يُنشئ ملف index.html
أيضًا حزمة تطوير البرامج (SDK) لتطبيق Cast، ويطلب من الدالة CastVideos
تحميلها.
يتم تحديد معظم المحتوى الذي سيعبئ هذه العناصر وإدراجه والتحكّم فيه في CastVideos.js
. لنلقِ نظرة على ذلك.
CastVideos.js
يدير هذا النص البرمجي كلّ المنطق الخاص بتطبيق الويب Cast Videos. وتتضمّن قائمة الفيديوهات والبيانات الوصفية المرتبطة بها والمحدّدة في CastVideos.js
عنصرًا باسم mediaJSON
.
هناك بعض الأقسام الرئيسية التي تتحمّل مسؤولية إدارة الفيديو وتشغيله على الجهاز وعلى الويب. بشكل عام، هذا تطبيق ويب بسيط إلى حدٍ ما.
CastPlayer
هي الفئة الرئيسية التي تدير التطبيق بأكمله، وإعداد المشغّل، واختيار الوسائط، وربط الأحداث بـ PlayerHandler
لتشغيل الوسائط. CastPlayer.prototype.initializeCastPlayer
هي الطريقة التي تهيئ جميع وظائف Cast. CastPlayer.prototype.switchPlayer
للتبديل بين حالة اللاعبين المحليين واللاعبين عن بُعد CastPlayer.prototype.setupLocalPlayer
وCastPlayer.prototype.setupRemotePlayer
لبدء تشغيل اللاعبين المحليين واللاعبين عن بُعد
PlayerHandler
هي الفئة المسؤولة عن إدارة تشغيل الوسائط. هناك عدد من الطرق الأخرى المسؤولة عن تفاصيل إدارة الوسائط وتشغيلها.
الأسئلة الشائعة
5- إضافة زر البث
تطبيق يعمل بتكنولوجيا Google Cast يعرض زر البث في عنصر الفيديو يؤدي النقر على زر البث إلى عرض قائمة بأجهزة البث التي يمكن للمستخدم اختيارها. إذا كان المستخدم يشغّل المحتوى على الجهاز المُرسِل، يؤدي اختيار جهاز بث إلى بدء التشغيل أو استئنافه على جهاز البث هذا. يمكن للمستخدم النقر على زر البث في أي وقت أثناء جلسة البث وإيقاف بث تطبيقك على جهاز البث. يجب أن يكون المستخدم قادرًا على الاتصال بجهاز البث أو إلغاء ربطه أثناء التواجد في أي شاشة لتطبيقك، كما هو موضح في قائمة التحقق من تصميم Google Cast.
الإعداد
يتطلب مشروع البدء نفس التبعيات والإعداد كما فعلت لنموذج التطبيق المكتمل، ولكن هذه المرة تستضيف محتوى app-start
.
في المتصفّح، انتقِل إلى عنوان URL https
للعيّنة التي استضفتها.
تذكَّر أنّه عند إجراء تغييرات، عليك إعادة استضافة العيّنة على خادمك استنادًا إلى الخدمة.
الإعداد
يحتوي إطار عمل Cast على عنصر فردي شامل، وهو CastContext
، الذي ينسق جميع أنشطة الإطار. يجب إعداد هذا الكائن في مرحلة مبكرة من دورة حياة التطبيق، وعادةً ما يتم استدعاؤه من خلال معاودة اتصال مُخصّصة لـ window['__onGCastApiAvailable']
، تُسمى بعد تحميل حزمة تطوير البرامج (SDK) الخاصة بالبث، وتكون متاحة للاستخدام. في هذه الحالة، يتمّ استدعاء CastContext
في CastPlayer.prototype.initializeCastPlayer
، والذي يتمّ استدعاؤه من خلال طلب إعادة الاتصال المذكور أعلاه.
يجب تقديم كائن options
JSON عند إعداد CastContext
. تحتوي هذه الفئة على خيارات تؤثر في سلوك إطار العمل. وأهم هذه المعلومات هو معرّف تطبيق المُستلِم، والذي يُستخدَم لفلترة قائمة أجهزة البث المتاحة لعرض الأجهزة القادرة على تشغيل التطبيق المحدّد فقط ولتشغيل تطبيق المُستلِم عند بدء جلسة بث.
عند تطوير تطبيق متوافق مع 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. لإجراء ذلك، علينا الاستماع إلى الأحداث المختلفة التي ينشئها إطار عمل Cast.
بث الوسائط
على المستوى العالي، إذا كنت تريد تشغيل الوسائط على جهاز بث، يجب أن يحدث ما يلي:
- أنشئ عنصر
MediaInfo
JSON
من حزمة تطوير البرامج (SDK) لتطبيق Cast الذي يمثّل عنصر وسائط. - يتصل المستخدم بجهاز البث لتشغيل تطبيق المُستلِم.
- حمِّل ملف
MediaInfo
في جهاز الاستقبال وشغِّل المحتوى. - تتبُّع حالة الوسائط
- إرسال أوامر التشغيل إلى المستلِم استنادًا إلى تفاعلات المستخدم
تؤدي الخطوة الأولى إلى ربط عنصر بآخر، وMediaInfo
هو عنصر يمكن لحزمة تطوير البرامج (SDK) لأجهزة البث فهمه، وmediaJSON
هو عنصر يُستخدم في تطبيقنا لتضمين عنصر وسائط، ويمكننا بسهولة ربط mediaJSON
بـ MediaInfo
. لقد أكملنا الخطوة 2 في القسم السابق. يمكنك تنفيذ الخطوة 3 بسهولة باستخدام حزمة تطوير البرامج (SDK) لتطبيق Cast.
يميز تطبيق CastPlayer
التجريبي بين التشغيل على الجهاز والتشغيل عن بُعد في طريقة switchPlayer
:
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
//...
ليس من المهم في هذا الدليل التعليمي أن تفهم بالضبط كيفية عمل كل منطق المشغّل النموذجي. ومع ذلك، من المهم معرفة أنّه يجب تعديل مشغّل الوسائط في تطبيقك ليتمكّن من رصد كلّ من التشغيل على الجهاز والتشغيل عن بُعد.
في الوقت الحالي، يكون المشغّل المحلي دائمًا في حالة التشغيل على الجهاز فقط لأنّه لا يعرف أي معلومات عن حالات البث إلى التلفزيون حتى الآن. نحتاج إلى تعديل واجهة المستخدم استنادًا إلى عمليات النقل بين الحالات التي تحدث في إطار عمل Cast. على سبيل المثال، إذا بدأنا البث، علينا إيقاف التشغيل على الجهاز وإيقاف بعض عناصر التحكّم. وبالمثل، إذا أوقفنا البث عندما نكون في وحدة التحكّم هذه، علينا الانتقال إلى التشغيل على الجهاز. لحلّ هذه المشكلة، علينا الاستماع إلى الأحداث المختلفة التي ينشئها إطار عمل Cast.
إدارة جلسة البث
بالنسبة إلى إطار عمل Cast، تجمع جلسة Cast خطوات الاتصال بجهاز وبدء جلسة (أو الانضمام إلى جلسة حالية) والاتصال بتطبيق مستقبل وبدء قناة التحكّم في الوسائط إذا لزم الأمر. قناة التحكّم في الوسائط هي الطريقة التي يرسل بها إطار عمل 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) الخاصة بالبث، توفّر RemotePlayer
وRemotePlayerController
مجموعة من واجهات برمجة التطبيقات المناسبة لإدارة تشغيل الوسائط عن بُعد على المستلِم. بالنسبة إلى CastSession
الذي يتيح تشغيل الوسائط، ستنشئ حزمة SDK تلقائيًا مثيلات RemotePlayer
وRemotePlayerController
. ويمكن الوصول إليهما من خلال إنشاء نُسخ من 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. تعتمد خدمة Cast Connect على البنية الأساسية للبث، ويعمل تطبيق Android TV كوحدة استقبال.
التبعيات
- الإصدار M87 أو إصدار أحدث من متصفِّح Chrome
ضبط Android Receiver Compatible
لتشغيل تطبيق Android TV، الذي يُعرف أيضًا باسم "مستقبل Android"، نحتاج إلى ضبط علامة androidReceiverCompatible
على "صحيح" في كائن 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) الآن تلقائيًا بيانات الاعتماد التي سيتم استخدامها في الجلسة الحالية.
اختبار الاتصال بالبث
خطوات تثبيت حزمة APK لنظام التشغيل Android TV على جهاز "Chromecast مع Google TV":
- ابحث عن عنوان IP لجهاز Android TV. وهي متاحة عادةً ضمن الإعدادات > الشبكة والإنترنت > (اسم الشبكة التي يتصل بها جهازك). على يسار الصفحة، ستظهر التفاصيل وعنوان IP لجهازك على الشبكة.
- استخدِم عنوان IP لجهازك للاتصال به عبر ADB باستخدام وحدة التحكّم الطرفية:
$ adb connect <device_ip_address>:5555
- من نافذة المحطة الطرفية، انتقِل إلى مجلد المستوى الأعلى لمحاكيات رمز Lab التي نزّلتها في بداية هذا الإصدار التجريبي من رمز Lab. على سبيل المثال:
$ cd Desktop/chrome_codelab_src
- ثبِّت ملف .apk في هذا المجلد على Android TV من خلال تشغيل:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- من المفترض أن يظهر لك الآن تطبيق باسم بث الفيديوهات في قائمة تطبيقاتك على جهاز Android TV.
- يمكنك تشغيل الرمز المُعدَّل للمُرسِل على الويب وبدء جلسة بث باستخدام جهاز Android TV باستخدام رمز البث أو اختيار
Cast..
من القائمة المنسدلة في متصفّح Chrome. من المفترض أن يؤدي ذلك الآن إلى تشغيل تطبيق Android TV على جهاز استقبال Android TV والسماح لك بالتحكّم في التشغيل باستخدام جهاز التحكّم عن بُعد في Android TV.
8. تهانينا
لقد تعرّفت الآن على كيفية تفعيل ميزة "البثّ" في تطبيق فيديو باستخدام التطبيقات المصغّرة لحزمة تطوير البرامج (SDK) لميزة "البثّ" على تطبيق ويب في Chrome.
لمزيد من التفاصيل، يُرجى الاطّلاع على دليل المطوّر الخاص بخدمة Web Sender.