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

يوضّح دليل المطوّرين هذا كيفية إضافة ميزة Google Cast إلى تطبيق Web Sender باستخدام حزمة تطوير البرامج (SDK) الخاصة بـ Cast.

المصطلحات

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

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

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

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

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

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

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

إطار العمل

تستخدِم حزمة تطوير البرامج (SDK) الخاصة بـ Web Sender مساحة الاسم cast.framework.*. تمثّل مساحة الاسم ما يلي:

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

يتألف الإطار من المكوّنات الرئيسية التالية:

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

راجِع مرجع Google Cast Web Sender API للحصول على وصف كامل لمساحة الاسم.

زر الإرسال

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

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

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

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

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

الإعداد

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

ضمن معالج الأحداث هذا، يمكنك بدء تفاعل Cast من خلال استدعاء طريقة 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 التي يمكن استخدامها لتنفيذ أي عمليات ضرورية للحصول على نتيجة ناجحة. إذا تم رفض Promise، سيكون وسيطة الدالة chrome.cast.ErrorCode.

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

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

يمنح RemotePlayerController التطبيق إذن التحكّم الكامل في الوسائط، بما في ذلك التشغيل والإيقاف المؤقت والإيقاف والبحث عن الوسائط المحمَّلة.

  • تشغيل/إيقاف مؤقت: playerController.playOrPause();
  • إيقاف: playerController.stop();
  • SEEK: 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;
  });

عندما تحدث أحداث مثل الإيقاف المؤقت أو التشغيل أو الاستئناف أو البحث، يجب أن يتفاعل التطبيق معها وأن تتم المزامنة بينه وبين تطبيق Web Receiver على جهاز Cast. يمكنك الاطّلاع على إشعارات الحالة لمزيد من المعلومات.

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

تقدّم حزمة تطوير البرامج (SDK) الخاصة بخدمة Cast مفهوم جلسة Cast، ويجمع إنشاء هذه الجلسة بين خطوات الاتصال بجهاز وتشغيل تطبيق Web Receiver (أو الانضمام إليه) والاتصال بهذا التطبيق وتهيئة قناة للتحكّم في الوسائط. اطّلِع على دليل دورة حياة التطبيق في Web Receiver للحصول على مزيد من المعلومات حول جلسات Cast ودورة حياة Web Receiver.

تتم إدارة الجلسات من خلال فئة CastContext، التي يمكن لتطبيقك استردادها من خلال cast.framework.CastContext.getInstance(). يتم تمثيل الجلسات الفردية بفئات فرعية من الفئة Session. على سبيل المثال، CastSession تمثّل الجلسات التي تستخدم أجهزة البث. يمكن لتطبيقك الوصول إلى جلسة Cast النشطة حاليًا من خلال 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 أو الشاشات الذكية. يتوقف تشغيل الوسائط على أحد الأجهزة (الجهاز المصدر) ويستمر على جهاز آخر (الجهاز الوجهة). يمكن لأي جهاز Cast مزوّد بأحدث البرامج الثابتة أن يكون مصدرًا أو وجهة لنقل البث.

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

لمزيد من المعلومات، راجِع مقالة نقل البث على Web Receiver.