دمج حزمة SDK للإرسال في تطبيق Web Sender

يوضّح دليل المطوِّر هذا طريقة إضافة دعم Google Cast إلى تطبيق Web Sender باستخدام حزمة Cast SDK.

المصطلحات

الجهاز الجوّال أو المتصفح هو المُرسِل الذي يتحكّم في التشغيل، وجهاز Google Cast هو المستلِم الذي يعرض المحتوى على الشاشة للتشغيل.

تتألف حزمة Web Sender SDK من جزأين: واجهة برمجة تطبيقات إطار العمل (cast.framework) وواجهة برمجة تطبيقات Base (chrome.cast) وبشكل عام، يتم إجراء طلبات على واجهة برمجة تطبيقات إطار العمل الأكثر بساطة والأعلى مستوى، والتي تتم معالجتها بعد ذلك بواسطة واجهة برمجة تطبيقات Base ذات المستوى الأدنى.

يشير إطار عمل المُرسِل إلى واجهة برمجة تطبيقات إطار العمل والوحدة والموارد المرتبطة بها والتي توفّر برنامجًا حول وظائف منخفضة المستوى. يشير تطبيق المُرسِل أو تطبيق Google Cast لمتصفِّح Chrome إلى تطبيق ويب (HTML/JavaScript) يتم تشغيله داخل متصفِّح Chrome على جهاز المُرسِل. يشير تطبيق جهاز استقبال الويب إلى تطبيق HTML/JavaScript يتم تشغيله على Chromecast أو جهاز Google Cast.

يستخدم إطار عمل المرسل تصميمًا غير متزامن لمعاودة الاتصال لإبلاغ تطبيق المرسِل بالأحداث وللانتقال بين الحالات المختلفة لدورة حياة تطبيق البثّ.

تحميل المكتبة

ليتمكّن تطبيقك من تنفيذ ميزات Google Cast، يحتاج التطبيق إلى معرفة موقع حزمة Google Cast Web Sender SDK، كما هو موضّح أدناه. أضِف مَعلمة طلب البحث لعنوان URL loadCastFramework لتحميل واجهة برمجة التطبيقات Web Sender إطار عمل. يجب أن تشير جميع صفحات تطبيقك إلى المكتبة على النحو التالي:

<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

إطار العمل

تستخدم حزمة تطوير البرامج (SDK) لمرسل الويب cast.framework.* namespace. تمثل مساحة الاسم ما يلي:

  • الطرق أو الدوال التي تستدعي عمليات على واجهة برمجة التطبيقات
  • أدوات معالجة الأحداث لوظائف أداة معالجة البيانات في واجهة برمجة التطبيقات

ويتكون إطار العمل من العناصر الرئيسية التالية:

  • CastContext عبارة عن كائن مفرد يوفر معلومات عن حالة البث الحالية ويشغّل أحداثًا عند حدوث تغييرات في حالة البث وحالة جلسة البث.
  • يدير كائن CastSession الجلسة، فهو يقدّم معلومات الحالة ويشغّل الأحداث، مثل التغييرات في مستوى صوت الجهاز وحالة كتم الصوت والبيانات الوصفية للتطبيق.
  • عنصر زر الإرسال، وهو عنصر HTML مخصّص بسيط يوسّع زر HTML. إذا لم يكن زر البث المعني كافيًا، يمكنك استخدام حالة البث لتنفيذ هذا الزر.
  • توفّر RemotePlayerController ربط البيانات لتبسيط تنفيذ المشغّل البعيد.

راجِع مرجع واجهة برمجة التطبيقات Google Cast Web Sender API للحصول على وصف كامل لمساحة الاسم.

زر الإرسال

يتم التعامل مع مكوِّن زر البث في تطبيقك بالكامل من خلال إطار العمل. ويشمل ذلك إدارة مستوى الظهور والتعامل مع أحداث النقرات.

<google-cast-launcher></google-cast-launcher>

بدلاً من ذلك، يمكنك إنشاء الزر آليًا:

document.createElement("google-cast-launcher");

يمكنك تطبيق أي تصميم إضافي، مثل المقاس أو الموضع، على العنصر حسب الضرورة. استخدِم السمة --connected-color لاختيار لون حالة "جهاز استقبال الويب" المتصل و--disconnected-color لحالة عدم الاتصال.

الإعداد

بعد تحميل واجهة برمجة التطبيقات لإطار العمل، سيستدعي التطبيق المعالج window.__onGCastApiAvailable. يجب التأكّد من أنّ التطبيق يضبط هذا المعالج على window قبل تحميل مكتبة المرسِل.

ضمن هذا المعالج، يمكنك إعداد تفاعل البثّ من خلال استدعاء طريقة setOptions(options) في CastContext.

مثال:

<script>
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    initializeCastApi();
  }
};
</script>

بعد ذلك، يمكنك إعداد واجهة برمجة التطبيقات على النحو التالي:

initializeCastApi = function() {
  cast.framework.CastContext.getInstance().setOptions({
    receiverApplicationId: applicationId,
    autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
  });
};

أولاً، يسترد التطبيق النسخة المفردة من عنصر CastContext الذي يوفّره إطار العمل. ثم يستخدم setOptions(options) باستخدام كائن CastOptions لضبط applicationID.

إذا كنت تستخدم "مستلِم الوسائط التلقائي" الذي لا يتطلب تسجيلاً، يمكنك استخدام معرّف ثابت محدّد مسبقًا بواسطة حزمة تطوير البرامج (SDK) لمُرسِل الويب، كما هو موضّح أدناه، بدلاً من applicationID:

cast.framework.CastContext.getInstance().setOptions({
  receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
});

التحكم في الوسائط

بعد إعداد CastContext، يمكن للتطبيق استرداد CastSession الحالية في أي وقت باستخدام getCurrentSession().

var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

يمكن استخدام CastSession لتحميل الوسائط على جهاز البثّ المرتبط باستخدام loadMedia(loadRequest). أولاً، أنشئ MediaInfo، باستخدام contentId وcontentType بالإضافة إلى أي معلومات أخرى ذات صلة بالمحتوى. بعد ذلك، أنشِئ LoadRequest منه، مع ضبط جميع المعلومات ذات الصلة بالطلب. وأخيرًا، اتصل بـ loadMedia(loadRequest) على جهاز CastSession.

var mediaInfo = new chrome.cast.media.MediaInfo(currentMediaURL, contentType);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  function() { console.log('Load succeed'); },
  function(errorCode) { console.log('Error code: ' + errorCode); });

ستعرض الطريقة loadMedia وعد يمكن استخدامه لتنفيذ أي عمليات ضرورية للحصول على نتيجة ناجحة. إذا تم رفض Promise، ستكون وسيطة الدالة هي chrome.cast.ErrorCode.

يمكنك الاطّلاع على متغيّرات حالة اللاعب في RemotePlayer. يتم التعامل مع كل التفاعلات مع RemotePlayer، بما في ذلك طلبات معاودة الاتصال بالأحداث الوسائط وأوامرها، من خلال RemotePlayerController.

var player = new cast.framework.RemotePlayer();
var playerController = new cast.framework.RemotePlayerController(player);

يتيح RemotePlayerController للتطبيق التحكّم في الوسائط بشكل كامل في PLAY و"الإيقاف المؤقت" و"الإيقاف" و"الطلب" في ما يتعلّق بالوسائط التي تم تحميلها.

  • التشغيل/الإيقاف المؤقت: playerController.playOrPause();
  • إيقاف: playerController.stop();
  • طلب: playerController.seek();

يمكن استخدام RemotePlayer وRemotePlayerController مع إطارات عمل ربط البيانات، مثل Polymer أو Angular، لتنفيذ مشغّل عن بُعد.

في ما يلي مقتطف رمز لـ Angular:

<button id="playPauseButton" class="playerButton"
  ng-disabled="!player.canPause"
  ng-click="controller.playOrPause()">
    {{player.isPaused ? 'Play' : 'Pause'}}
</button>
<script>
var player = new cast.framework.RemotePlayer();
var controller = new cast.framework.RemotePlayerController(player);
// Listen to any player update, and trigger angular data binding
update.controller.addEventListener(
  cast.framework.RemotePlayerEventType.ANY_CHANGE,
  function(event) {
    if (!$scope.$$phase) $scope.$apply();
  });
</script>

حالة الوسائط

أثناء تشغيل الوسائط، تقع أحداث مختلفة يمكن تسجيلها من خلال ضبط المستمعين لأحداث cast.framework.RemotePlayerEventType مختلفة على كائن RemotePlayerController.

للحصول على معلومات عن حالة الوسائط، استخدِم الحدث cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED الذي يتم تشغيله عند حدوث تغيير في التشغيل وعند حدوث تغيير في CastSession.getMediaSession().media.

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.MEDIA_INFO_CHANGED, function() {
    // Use the current session to get an up to date media status.
    let session = cast.framework.CastContext.getInstance().getCurrentSession();

    if (!session) {
        return;
    }

    // Contains information about the playing media including currentTime.
    let mediaStatus = session.getMediaSession();
    if (!mediaStatus) {
        return;
    }

    // mediaStatus also contains the mediaInfo containing metadata and other
    // information about the in progress content.
    let mediaInfo = mediaStatus.media;
  });

وعند وقوع أحداث مثل الإيقاف المؤقت أو التشغيل أو الاستئناف أو البحث، سيحتاج التطبيق إلى اتخاذ إجراء بشأنها والمزامنة بينها وبين تطبيق مستقبِل الويب على جهاز البث. راجِع تحديثات الحالة للحصول على مزيد من المعلومات.

آلية عمل إدارة الجلسات

تقدّم حزمة تطوير البرامج (SDK) الخاصة بالبثّ مفهوم جلسة Google Cast، وهي تجمع بين خطوات الاتصال بجهاز وإطلاق (أو ربط) تطبيق جهاز استقبال الويب والاتصال بهذا التطبيق وإعداد قناة التحكّم في الوسائط. يمكنك الاطّلاع على دليل دورة حياة التطبيق لمزيد من المعلومات حول جلسات البثّ ودورة حياة جهاز استقبال الويب.

تتم إدارة الجلسات بواسطة الصف CastContext، الذي يمكن لتطبيقك استرداده من خلال cast.framework.CastContext.getInstance(). ويتم تمثيل الجلسات الفردية بفئات فرعية من الفئة Session. على سبيل المثال، يمثل الرمز CastSession الجلسات مع أجهزة البث. يمكن لتطبيقك الوصول إلى جلسة البث النشطة حاليًا من خلال CastContext.getCurrentSession().

لمراقبة حالة الجلسة، أضِف أداة معالجة إلى CastContext لنوع حدث CastContextEventType.SESSION_STATE_CHANGED.

var context = cast.framework.CastContext.getInstance();
context.addEventListener(
  cast.framework.CastContextEventType.SESSION_STATE_CHANGED,
  function(event) {
    switch (event.sessionState) {
      case cast.framework.SessionState.SESSION_STARTED:
      case cast.framework.SessionState.SESSION_RESUMED:
        break;
      case cast.framework.SessionState.SESSION_ENDED:
        console.log('CastContext: CastSession disconnected');
        // Update locally as necessary
        break;
    }
  })

لقطع الاتصال، مثلاً عندما ينقر المستخدم على زر "إيقاف البث" من مربّع حوار البثّ، يمكنك إضافة أداة معالجة إلى نوع حدث RemotePlayerEventType.IS_CONNECTED_CHANGED ضمن المستمع. يتحقق المستمع ممّا إذا كان RemotePlayer غير متّصلة. في هذه الحالة، عدِّل حالة المشغّل المحلي حسب الضرورة. مثال:

playerController.addEventListener(
  cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
    if (!player.isConnected) {
      console.log('RemotePlayerController: Player disconnected');
      // Update local player to disconnected state
    }
  });

يستطيع المستخدم التحكّم مباشرةً في إنهاء البث من خلال زر البث في إطار العمل، ولكن يمكن للمرسِل نفسه إيقاف البث باستخدام عنصر CastSession الحالي.

function stopCasting() {
  var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
  // End the session and pass 'true' to indicate
  // that Web Receiver app should be stopped.
  castSession.endSession(true);
}

نقل البث

يمثّل الحفاظ على حالة الجلسة أساس نقل البث، حيث يمكن للمستخدمين نقل المحتوى الصوتي والفيديوهات الحالية على مختلف الأجهزة باستخدام الطلبات الصوتية أو تطبيق Google Home أو الشاشات الذكية. يتوقف تشغيل الوسائط على أحد الأجهزة (المصدر) ويستمر تشغيلها على جهاز آخر (الوجهة). يمكن استخدام أي جهاز بث مزوّد بأحدث البرامج الثابتة كمصادر أو وجهات في عملية نقل البث.

للحصول على جهاز الوجهة الجديد أثناء نقل البث، يمكنك الاتصال بالرمز CastSession#getCastDevice() عند استدعاء حدث cast.framework.SessionState.SESSION_RESUMED.

راجِع نقل البث على جهاز استقبال الويب للحصول على مزيد من المعلومات.