במדריך הזה למפתחים מוסבר איך להוסיף תמיכה ב-Google Cast לאפליקציית Web Sender באמצעות Cast SDK.
הסברים על המונחים
המכשיר הנייד או הדפדפן הוא השולח, ששולט בהפעלה. מכשיר Google Cast הוא המקבל, שמציג את התוכן במסך להפעלה.
Web Sender SDK מורכב משני חלקים: Framework API (cast.framework) ו-Base API (chrome.cast). באופן כללי, אתם מבצעים קריאות ל-Framework API הפשוט יותר ברמה גבוהה יותר, ולאחר מכן הן מעובדות על ידי Base API ברמה נמוכה יותר.
Sender framework מתייחס ל-Framework API, למודול ולמשאבים המשויכים שמספקים מעטפת לפונקציונליות ברמה נמוכה יותר. אפליקציית השליחה או אפליקציית Google Cast ל-Chrome היא אפליקציית אינטרנט (HTML/JavaScript) שפועלת בדפדפן Chrome במכשיר השולח. אפליקציית Web Receiver היא אפליקציית HTML/JavaScript שפועלת ב-Chromecast או במכשיר Google Cast.
מסגרת השולח משתמשת בעיצוב של קריאה חוזרת (callback) אסינכרונית כדי להודיע לאפליקציית השולח על אירועים ולעבור בין מצבים שונים של מחזור החיים של אפליקציית 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
ה-Web Sender SDK משתמש במרחב השמות cast.framework.*. מרחב השמות מייצג את הדברים הבאים:
- שיטות או פונקציות שמפעילות פעולות ב-API
- רכיבי event listener לפונקציות של ה-listener ב-API
המסגרת מורכבת מהרכיבים העיקריים הבאים:
- האובייקט
CastContextהוא אובייקט יחיד שמספק מידע על מצב ה-Cast הנוכחי, ומפעיל אירועים לשינויים במצב ה-Cast ובמצב הסשן של Cast. - האובייקט
CastSessionמנהל את הסשן – הוא מספק מידע על המצב ומפעיל אירועים, כמו שינויים בעוצמת הקול של המכשיר, מצב ההשתקה ומטא-נתונים של האפליקציה. - רכיב הכפתור להפעלת Cast, שהוא רכיב HTML פשוט בהתאמה אישית שמרחיב את כפתור ה-HTML. אם הכפתור להפעלת Cast שסופק לא מספיק, אתם יכולים להשתמש במצב Cast כדי להטמיע כפתור להפעלת Cast.
RemotePlayerControllerמספק את קישור הנתונים כדי לפשט את ההטמעה של הנגן המרוחק.
במאמרי העזרה של Google Cast Web Sender API יש תיאור מלא של מרחב השמות.
כפתור הפעלת Cast
רכיב הכפתור להפעלת Cast באפליקציה מטופל כולו על ידי ה-framework. זה כולל ניהול של החשיפה וגם טיפול באירועים מסוג קליק.
<google-cast-launcher></google-cast-launcher>
לחלופין, אפשר ליצור את הלחצן באופן פרוגרמטי:
document.createElement("google-cast-launcher");
אפשר להחיל על הרכיב כל סגנון נוסף, כמו גודל או מיקום, לפי הצורך. משתמשים במאפיין --connected-color כדי לבחור את הצבע של מצב החיבור של Web Receiver, ובמאפיין --disconnected-color כדי לבחור את הצבע של מצב הניתוק.
אתחול
אחרי טעינת ה-API של המסגרת, האפליקציה תפעיל את ה-handler window.__onGCastApiAvailable. חשוב לוודא שהאפליקציה מגדירה את ה-handler הזה ב-window לפני טעינת ספריית השולח.
בתוך ה-handler הזה, מאתחלים את האינטראקציה של Cast באמצעות קריאה ל-method 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
});
};
קודם כל, האפליקציה מאחזרת את המופע היחיד של האובייקט CastContext שסופק על ידי ה-framework. לאחר מכן, הוא משתמש ב-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); });
ה-method 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". כשמגדירים סשן Cast, משלבים את השלבים של התחברות למכשיר, הפעלה של אפליקציית Web Receiver (או הצטרפות אליה), התחברות לאפליקציה הזו ואתחול של ערוץ ממשק השליטה במדיה. למידע נוסף על סשנים של Cast ועל מחזור החיים של Web Receiver, עיינו במדריך למחזור החיים של אפליקציית Web Receiver.
הסשנים מנוהלים על ידי המחלקה 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;
}
})
כדי לנתק את החיבור, למשל כשהמשתמש לוחץ על הלחצן "הפסקת ההעברה" בתיבת הדו-שיח של Cast, אפשר להוסיף מאזין לסוג האירוע 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
}
});
המשתמש יכול לשלוט ישירות בהפסקת ה-Cast באמצעות הכפתור להפעלת Cast, אבל השולח עצמו יכול להפסיק את ה-Cast באמצעות האובייקט הנוכחי של 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.