שילוב Cast SDK באפליקציית Web Sender

במדריך למפתחים הזה מוסבר איך להוסיף תמיכה ב-Google Cast לאפליקציית Web Sender באמצעות Cast SDK.

הסברים על המונחים

המכשיר הנייד או הדפדפן הם השולח, ששולט בהפעלה. מכשיר 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, היא צריכה לדעת את המיקום של Google Cast Web Sender SDK, כפי שמתואר בהמשך. מוסיפים את פרמטר השאילתה של כתובת ה-URL loadCastFramework כדי לטעון גם את Web Sender Framework API. כל הדפים באפליקציה חייבים להפנות לספרייה באופן הבא:

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

Framework

ה-SDK של Web Sender משתמש במרחב השמות cast.framework.*. מרחב השמות מייצג את הנתונים הבאים:

  • שיטות או פונקציות שמפעילות פעולות ב-API
  • פונקציות event listener לפונקציות של רכיבי ה-listener ב-API

המסגרת מורכבת מהרכיבים העיקריים הבאים:

  • CastContext הוא אובייקט יחיד (singleton) שמספק מידע על המצב הנוכחי של Cast ומפעיל אירועים לגבי שינויים במצב של Cast ובמצב של סשן Cast.
  • האובייקט CastSession מנהל את הסשן – הוא מספק מידע על המצב ומפעיל אירועים, כמו שינויים בנפח המכשיר, במצב ההשתקה ובמטא-נתונים של האפליקציה.
  • אלמנט הלחצן להפעלת Cast, שהוא אלמנט HTML פשוט בהתאמה אישית שמרחיב את הלחצן ב-HTML. אם הלחצן להעברה (cast) שסופק לא מספיק, תוכלו להשתמש במצב ההעברה (cast) כדי להטמיע לחצן להעברה.
  • ה-RemotePlayerController מספק את קישור הנתונים כדי לפשט את ההטמעה של הנגן המרוחק.

תיאור מלא של מרחב השמות זמין במאמר Google Cast Web Sender API Reference.

לחצן הפעלת Cast

המערכת מטפלת באופן מלא ברכיב של הלחצן להפעלת Cast באפליקציה. הניהול כולל ניהול של הרשאות הגישה וטיפול באירועי קליקים.

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

לחלופין, אפשר ליצור את הלחצן באופן פרוגרמטי:

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

אפשר להחיל על הרכיב סגנון נוסף, כמו גודל או מיקום, לפי הצורך. משתמשים במאפיין --connected-color כדי לבחור את הצבע של המצב 'מקלט אינטרנט מחובר', ובמאפיין --disconnected-color כדי לבחור את הצבע של המצב 'מקלט אינטרנט מנותק'.

אתחול

אחרי טעינת ה-API של המסגרת, האפליקציה תפנה למטפל window.__onGCastApiAvailable. חשוב לוודא שהאפליקציה מגדירה את הטיפול הזה ב-window לפני טעינת ספריית השולח.

בתוך ה-handler הזה, מאתחלים את האינטראקציה של Cast באמצעות קריאה לשיטה setOptions(options) של CastContext.

לדוגמה:

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

לאחר מכן מאתחלים את ה-API באופן הבא:

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

קודם האפליקציה מאחזרת את מופע היחיד (singleton) של האובייקט CastContext שסופק על ידי המסגרת. לאחר מכן, הוא משתמש ב-setOptions(options) באמצעות אובייקט CastOptions כדי להגדיר את applicationID.

אם אתם משתמשים ב-Default Media Receiver, שלא מחייב רישום, צריך להשתמש בערך קבוע שהוגדר מראש על ידי Web Sender 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 כדי לטעון מדיה למכשיר Cast המחובר באמצעות 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, כולל קריאות חזרה (callbacks) ופקדים של אירועי מדיה, מטופלות באמצעות RemotePlayerController.

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

ה-RemotePlayerController מעניק לאפליקציה שליטה מלאה על המדיה, כולל הפעלה, השהיה, עצירה וסריקה של המדיה שנטענה.

  • הפעלה/השהיה: playerController.playOrPause();
  • STOP: ‏ 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). מידע נוסף זמין במאמר עדכוני סטטוס.

איך פועל ניהול הסשנים

ב-Cast SDK מוצג הקונספט של סשן Cast, שבו השלבים של חיבור למכשיר, הפעלה (או הצטרפות) לאפליקציית Web Receiver, חיבור לאפליקציה הזו והפעלת ערוץ לניהול מדיה משולבים. למידע נוסף על סשנים של העברה (cast) ועל מחזור החיים של מקלט האינטרנט, אפשר לעיין במדריך למחזור החיים של אפליקציות.

הסשנים מנוהלים על ידי הכיתה CastContext, והאפליקציה יכולה לאחזר אותה דרך cast.framework.CastContext.getInstance(). סשנים ספציפיים מיוצגים על ידי תת-כיתות של הכיתה Session. לדוגמה, הערך CastSession מייצג סשנים במכשירי Cast. האפליקציה יכולה לגשת לסשן ההעברה (cast) הפעיל באמצעות CastContext.getCurrentSession().

כדי לעקוב אחרי מצב הסשן, מוסיפים listener ל-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;
    }
  })

במקרה של ניתוק, למשל כשהמשתמש לוחץ על הלחצן 'הפסקת ההעברה' בתיבת הדו-שיח של ההעברה, אפשר להוסיף ל-listener listener לסוג האירוע 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.