דף זה מכיל קטעי קוד ותיאורים של התכונות הזמינות באפליקציה מותאמת אישית של פרוטוקול אינטרנט.
- אלמנט
cast-media-player
שמייצג את ממשק המשתמש המובנה של הנגן, שסופק עם WebReceiver. - עיצוב דמוי-CSS מותאם אישית לאלמנט
cast-media-player
כדי לסגנן רכיבי ממשק משתמש שונים, כמוbackground-image
,splash-image
ו-font-family
. - רכיב סקריפט לטעינת ה-framework של Getr.
- קוד JavaScript ליירוט הודעות ולטיפול באירועים.
- 'הבאים בתור' להפעלה אוטומטית.
- אפשרויות להגדרת ההפעלה.
- אפשרויות להגדרת ההקשר של Web Aware.
- אפשרויות להגדרת פקודות שנתמכות על ידי האפליקציה Web Acceptr.
- קריאת JavaScript להפעלת האפליקציה Web Acceptr.
תצורה ואפשרויות של אפליקציה
הגדרת האפליקציה
CastReceiverContext
הוא המחלקה החיצונית ביותר שנחשפה למפתח, והוא מנהל את הטעינה של ספריות בסיסיות ומטפל באתחול של Web Acceptr SDK. ה-SDK מספק ממשקי API שמאפשרים למפתחי אפליקציות להגדיר את ה-SDK באמצעות CastReceiverOptions
.
ההגדרות האלה נבדקות פעם אחת בכל הפעלה של האפליקציה, והן מועברות ל-SDK כשמגדירים את הפרמטר האופציונלי בקריאה ל-start
.
הדוגמה הבאה מראה איך לשנות את התנהגות ברירת המחדל כדי לזהות אם חיבור השולח עדיין מחובר. כשמקלט האינטרנט לא מצליח לתקשר עם שולח במשך maxInactivity
שניות, נשלח אירוע SENDER_DISCONNECTED
. התצורה שבהמשך מבטלת את הזמן הקצוב לתפוגה. ההגדרה הזו יכולה להיות שימושית לניפוי באגים כי היא מונעת מהאפליקציה Web Acceptr לסגור את הסשן של Chrome Remote Debugger כשאין שולחים מחוברים במצב IDLE
.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
הגדרת הנגן
כשטוענים תוכן, ה-WebReceiver SDK מאפשר להגדיר משתני הפעלה כמו פרטי DRM, ניסיון חוזר ורכיבי handler של בקשות באמצעות cast.framework.PlaybackConfig
.
המידע הזה מטופל על ידי PlayerManager
ונבדק בזמן יצירת השחקנים. הנגנים נוצרים בכל פעם שטעינה חדשה מועברת ל-Web Acceptr SDK. שינויים ב-PlaybackConfig
אחרי יצירת הנגן נבדקים בטעינת התוכן הבאה. ה-SDK מספק את השיטות הבאות לשינוי
PlaybackConfig
.
CastReceiverOptions.playbackConfig
כדי לשנות את אפשרויות ההגדרה שמוגדרות כברירת מחדל באתחולCastReceiverContext
.PlayerManager.getPlaybackConfig()
על מנת לקבל את ההגדרות הנוכחיות.PlayerManager.setPlaybackConfig()
כדי לשנות את ההגדרות הנוכחיות. ההגדרה הזו תחול על כל הטעינות הבאות, או עד שמשנים אותה שוב.PlayerManager.setMediaPlaybackInfoHandler()
כדי להחיל הגדרות נוספות רק על פריט המדיה שנטען מעל ההגדרות הנוכחיות. ה-handler מופעל ממש לפני יצירת הנגן. שינויים שמתבצעים כאן הם לא קבועים ולא כלולים בשאילתות שלgetPlaybackConfig()
. כשפריט המדיה הבא ייטען, ה-handler הזה יופעל שוב.
הדוגמה הבאה ממחישה איך להגדיר את PlaybackConfig
כשמאתחלים את CastReceiverContext
. ההגדרה מבטלת בקשות יוצאות לקבלת מניפסטים. ה-handler מציין שבקשות CORS Access-Control צריכות להתבצע באמצעות פרטי כניסה כמו קובצי cookie או כותרות הרשאות.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
הדוגמה הבאה מראה איך לעקוף את PlaybackConfig
באמצעות getter ו-setter שסופק ב-PlayerManager
. ההגדרה מגדירה את הנגן
להמשיך את הפעלת התוכן אחרי טעינת קטע אחד.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
בדוגמה הבאה מוסבר איך לעקוף את PlaybackConfig
של בקשת טעינה ספציפית באמצעות handler של פרטי הפעלת מדיה. ה-handler קורא לשיטה שהוטמעה getLicenseUrlForMedia
כדי לקבל את licenseUrl
מה-contentId
של הפריט הנוכחי.
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
האזנה לאירוע
ה-Web Acceptr SDK מאפשר לאפליקציה WebReceiver לטפל באירועי נגן. ה-event listener משתמש בפרמטר cast.framework.events.EventType
(או מערך של הפרמטרים האלה) שמציין את האירועים שצריכים להפעיל את ה-listener. מערכים מוגדרים מראש של cast.framework.events.EventType
, שימושיים לניפוי באגים, נמצאים ב-cast.framework.events.category
.
פרמטר האירוע מספק מידע נוסף על האירוע.
לדוגמה, אם רוצים לדעת מתי משודר שינוי ב-mediaStatus
, אפשר להשתמש בלוגיקה הבאה כדי לטפל באירוע:
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
cast.framework.events.EventType.MEDIA_STATUS, (event) => {
// Write your own event handling code, for example
// using the event.mediaStatus value
});
יירוט הודעות
ה-WebReceiver SDK מאפשר לאפליקציה Web Acceptr ליירט הודעות ולהפעיל קוד מותאם אישית בהודעות האלה. יירוט ההודעות משתמש בפרמטר cast.framework.messages.MessageType
שמציין את סוג ההודעה שצריך ליירט.
הכלי המיירט צריך להחזיר את הבקשה ששונתה או הבטחה שמסתיימת עם ערך הבקשה שהשתנה. כשמחזירים את null
, לא תהיה אפשרות לקרוא ל-handler שמוגדר כברירת מחדל. פרטים נוספים זמינים בקטע טעינת מדיה.
לדוגמה, אם רוצים לשנות את הנתונים של בקשת הטעינה, אפשר להשתמש בלוגיקה הבאה כדי ליירט ולשנות אותם:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_FAILED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
if (!loadRequestData.media.entity) {
return loadRequestData;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
if (!asset) {
throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
}
loadRequestData.media.contentUrl = asset.url;
loadRequestData.media.metadata = asset.metadata;
loadRequestData.media.tracks = asset.tracks;
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
context.start();
טיפול בשגיאות
כאשר מתרחשות שגיאות במיירט ההודעות, האפליקציה WebReceiver צריכה להחזיר cast.framework.messages.ErrorType
וגם cast.framework.messages.ErrorReason
מתאימים.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_CANCELLED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
...
return fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
...
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
יירוט הודעות לעומת האזנה לאירוע
לפניכם כמה מההבדלים העיקריים בין יירוט הודעות לבין האזנה לאירועים:
- event listener לא מאפשר לשנות את נתוני הבקשה.
- התכונה event listener היא השיטה הטובה ביותר להפעלת ניתוח נתונים או פונקציה בהתאמה אישית.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- יירוט הודעות מאפשר לכם להאזין להודעה, ליירט אותה ולשנות את נתוני הבקשה עצמם.
- יירוט הודעות מומלץ במיוחד לטיפול בלוגיקה מותאמת אישית בנוגע לבקשות נתונים.
המדיה בטעינה
MediaInformation
מספק מאפיינים רבים לטעינת מדיה בהודעת cast.framework.messages.MessageType.LOAD
, כולל entity
, contentUrl
ו-contentId
.
entity
הוא המאפיין המוצע לשימוש בהטמעה של האפליקציות של השולח ושל המקבל. הנכס הוא כתובת URL של קישור עומק, שיכול להיות של פלייליסט או תוכן מדיה. עליכם לנתח את כתובת ה-URL הזו ולאכלס לפחות אחד משני השדות האחרים.- הסמל
contentUrl
תואם לכתובת ה-URL שבה הנגן ישתמש כדי לטעון את התוכן. לדוגמה, כתובת ה-URL הזו יכולה להפנות למניפסט DASH. contentId
יכול להיות כתובת URL של תוכן שניתן להפעיל (דומה לזו של הנכסcontentUrl
) או מזהה ייחודי של התוכן או הפלייליסט שנטענים. אם משתמשים במאפיין הזה כמזהה, האפליקציה צריכה לאכלס כתובת URL שניתן להפעיל ב-contentUrl
.
ההצעה היא להשתמש ב-entity
כדי לשמור את המזהה האמיתי או את הפרמטרים של המפתח, ולהשתמש ב-contentUrl
לכתובת ה-URL של המדיה. דוגמה לכך מוצגת בקטע הקוד הבא, שבו entity
נמצא בבקשה LOAD
וה-contentUrl
שניתן להפעלה מאוחזר:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
...
if (!loadRequestData.media.entity) {
// Copy the value from contentId for legacy reasons if needed
loadRequestData.media.entity = loadRequestData.media.contentId;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
loadRequestData.media.contentUrl = asset.url;
...
return loadRequestData;
});
});
יכולות המכשיר
השיטה getDeviceCapabilities
מספקת מידע על המכשיר במכשיר ה-Cast המחובר ובמכשיר הווידאו או האודיו שמחובר אליו. השיטה getDeviceCapabilities
מספקת פרטי תמיכה לגבי Google Assistant, Bluetooth, הצגות ואודיו המחוברים.
השיטה הזו מחזירה אובייקט שאפשר להריץ עליו שאילתה על ידי העברת אחד מהטיפוסים שצוינו כדי לקבל את יכולת המכשיר עבור אותם טיפוסים בני מנייה (enum). הטיפוסים הטיפוסיים מוגדרים ב-cast.framework.system.DeviceCapabilities
.
הדוגמה הזו בודקת אם המכשיר ב-Web Aware יכול להפעיל HDR ו-DolbyVision (DV) באמצעות המקשים IS_HDR_SUPPORTED
ו-IS_DV_SUPPORTED
, בהתאמה.
const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
const deviceCapabilities = context.getDeviceCapabilities();
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
}
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
}
});
context.start();
טיפול באינטראקציה של משתמשים
המשתמש יכול לקיים אינטראקציה עם אפליקציית Web Aware באמצעות אפליקציות של השולח (אינטרנט, Android ו-iOS), פקודות קוליות במכשירים עם Assistant מובנית, מקשי מגע במסכים חכמים ושלט רחוק במכשירי Android TV. ה-SDK של Cast מספק ממשקי API שונים כדי לאפשר לאפליקציה Web Acceptr לטפל באינטראקציות האלה, לעדכן את ממשק המשתמש של האפליקציה באמצעות מצבים של פעולות משתמש, ואפשר גם לשלוח את השינויים כדי לעדכן את השירותים לקצה העורפי.
פקודות מדיה נתמכות
המצבים של פקדים בממשק המשתמש מבוססים על MediaStatus.supportedMediaCommands
לבקרים מורחבים, לאפליקציות של מקלטים ושל שלטים מרחוק שפועלות במכשירי מגע ואפליקציות עבור מקלטים במכשירי Android TV. כשמפעילים בנכס Command
מסוים ברמת הסיביות, הלחצנים שקשורים לפעולה הזו מופעלים. אם הערך לא מוגדר, הלחצן מושבת. ניתן לשנות את הערכים האלה ב-WebReceiver על ידי:
- אם משתמשים ב-
PlayerManager.setSupportedMediaCommands
כדי להגדיר את המאפייןCommands
- הוספת פקודה חדשה באמצעות
addSupportedMediaCommands
- מסירים פקודה קיימת באמצעות
removeSupportedMediaCommands
.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
כשהמקבל יכין את MediaStatus
המעודכן, הוא יכלול את השינויים בנכס supportedMediaCommands
. כשהסטטוס משודר, אפליקציות השולחים המקושרות יעדכנו את הלחצנים בממשק המשתמש שלהן בהתאם.
למידע נוסף על פקודות מדיה נתמכות ועל מכשירי מגע, עיינו במדריך Accessing UI controls
.
ניהול מצבים של פעולות משתמשים
כשמשתמשים מבצעים אינטראקציה עם ממשק המשתמש או שולחים פקודות קוליות, הם יכולים לשלוט בהפעלה של התוכן והמאפיינים שקשורים לפריט המופעל. הבקשות ששולטות בהפעלה מטופלות באופן אוטומטי על ידי ה-SDK. בקשות שמשנות את המאפיינים של הפריט הנוכחי שמופעל, כמו פקודת LIKE
, מצריכות שאפליקציית המקבל תטפל בהן. ב-SDK יש סדרה של ממשקי API לטיפול בבקשות מהסוגים האלה. על מנת לתמוך בבקשות האלה, צריך לבצע את הפעולות הבאות:
- מגדירים את
MediaInformation
userActionStates
עם העדפות המשתמש בזמן טעינת פריט מדיה. - יירוט
USER_ACTION
הודעות וקבע את הפעולה המבוקשת. - כדי לעדכן את ממשק המשתמש, צריך לעדכן את
MediaInformation
UserActionState
.
קטע הקוד הבא מיירט את הבקשה LOAD
ומאכלס את MediaInformation
של LoadRequestData
. במקרה הזה, המשתמש אוהב את התוכן שנטען.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
const userActionLike = new cast.framework.messages.UserActionState(
cast.framework.messages.UserAction.LIKE);
loadRequestData.media.userActionStates = [userActionLike];
return loadRequestData;
});
קטע הקוד הבא מיירט את ההודעה USER_ACTION
ומטפל בקריאה לקצה העורפי עם השינוי המבוקש. לאחר מכן, מבצעת שיחה כדי לעדכן את השדה UserActionState
במקבל.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
(userActionRequestData) => {
// Obtain the media information of the current content to associate the action to.
let mediaInfo = playerManager.getMediaInformation();
// If there is no media info return an error and ignore the request.
if (!mediaInfo) {
console.error('Not playing media, user action is not supported');
return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
}
// Reach out to backend services to store user action modifications. See sample below.
return sendUserAction(userActionRequestData, mediaInfo)
// Upon response from the backend, update the client's UserActionState.
.then(backendResponse => updateUserActionStates(backendResponse))
// If any errors occurred in the backend return them to the cast receiver.
.catch((error) => {
console.error(error);
return error;
});
});
קטע הקוד הבא מדמה קריאה לשירות לקצה העורפי. הפונקציה בודקת את UserActionRequestData
כדי לראות את סוג השינוי שהמשתמש ביקש, ומבצעת קריאה לרשת רק אם הפעולה נתמכת על ידי הקצה העורפי.
function sendUserAction(userActionRequestData, mediaInfo) {
return new Promise((resolve, reject) => {
switch (userActionRequestData.userAction) {
// Handle user action changes supported by the backend.
case cast.framework.messages.UserAction.LIKE:
case cast.framework.messages.UserAction.DISLIKE:
case cast.framework.messages.UserAction.FOLLOW:
case cast.framework.messages.UserAction.UNFOLLOW:
case cast.framework.messages.UserAction.FLAG:
case cast.framework.messages.UserAction.SKIP_AD:
let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
setTimeout(() => {resolve(backendResponse)}, 1000);
break;
// Reject all other user action changes.
default:
reject(
new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
}
});
}
קטע הקוד הבא לוקח את UserActionRequestData
ומוסיף או מסיר את UserActionState
מה-MediaInformation
. עדכון השדה UserActionState
של MediaInformation
משנה את המצב של הלחצן שמשויך לפעולה המבוקשת. השינוי הזה יבוא לידי ביטוי בממשק המשתמש של הפקדים במסכים החכמים, באפליקציה של השלט הרחוק ובממשק המשתמש של Android TV. הוא משודר גם באמצעות הודעות MediaStatus
יוצאות, כדי לעדכן את ממשק המשתמש של הבקר המורחב לשולחים ב-iOS וב-Android.
function updateUserActionStates(backendResponse) {
// Unwrap the backend response.
let mediaInfo = backendResponse.mediaInfo;
let userActionRequestData = backendResponse.userActionRequestData;
// If the current item playing has changed, don't update the UserActionState for the current item.
if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
return;
}
// Check for existing userActionStates in the MediaInformation.
// If none, initialize a new array to populate states with.
let userActionStates = mediaInfo.userActionStates || [];
// Locate the index of the UserActionState that will be updated in the userActionStates array.
let index = userActionStates.findIndex((currUserActionState) => {
return currUserActionState.userAction == userActionRequestData.userAction;
});
if (userActionRequestData.clear) {
// Remove the user action state from the array if cleared.
if (index >= 0) {
userActionStates.splice(index, 1);
}
else {
console.warn("Could not find UserActionState to remove in MediaInformation");
}
} else {
// Add the UserActionState to the array if enabled.
userActionStates.push(
new cast.framework.messages.UserActionState(userActionRequestData.userAction));
}
// Update the UserActionState array and set the new MediaInformation
mediaInfo.userActionStates = userActionStates;
playerManager.setMediaInformation(mediaInfo, true);
return;
}
פקודות קוליות
פקודות המדיה הבאות נתמכות בשלב זה ב-Web Acceptr SDK במכשירים עם Assistant מובנית. יישומי ברירת המחדל של הפקודות האלה נמצאים ב-cast.framework.PlayerManager
.
פקודה | תיאור |
---|---|
Play | להפעיל או להמשיך את ההפעלה ממצב מושהה. |
השהיה | השהיית התוכן שמופעל עכשיו. |
הקודם | דילוג לפריט המדיה הקודם בתור המדיה. |
הבא | דילוג לפריט המדיה הבא בתור. |
עצירה | לעצור את המדיה שפועלת עכשיו. |
ללא חזרה | השבתת החזרה על פריטי מדיה בתור ברגע שההפעלה של הפריט האחרון בתור הסתיימה. |
חזרה יחידה | חוזרים על המדיה שפועלת עכשיו ללא הגבלת זמן. |
חזרה על הכול | חוזרים על כל הפריטים בתור עם הפעלת הפריט האחרון בתור. |
חזרה על הכול והקצאה אקראית | ברגע שהסתיימה ההפעלה של הפריט האחרון בתור, מסדרים את התור בסדר אקראי וחוזרים על כל הפריטים בתור. |
באקראי | סידור פריטי מדיה בסדר אקראי בתור המדיה. |
הפעלה או השבתה של הכתוביות | הפעלה / השבתה של כתוביות במדיה. האפשרות 'הפעלה / השבתה' זמינה גם לפי שפה. |
הרצה עד לערך המוחלט | מעבר לזמן המוחלט שצוין. |
הרצה לזמן ביחס לזמן הנוכחי | דילוג קדימה או אחורה לפי תקופת הזמן שצוינה ביחס לזמן ההפעלה הנוכחי. |
לשחק שוב | מפעילים מחדש את המדיה שפועלת כרגע או את פריט המדיה האחרון שהופעל אם שום דבר לא מופעל כרגע. |
הגדרת קצב ההפעלה | שינוי קצב ההפעלה של המדיה. צריך לטפל באפשרות הזו כברירת מחדל. אפשר להשתמש במיירט ההודעות SET_PLAYBACK_RATE כדי לבטל בקשות לשיעור נכנסות. |
פקודות קוליות נתמכות במדיה
כדי למנוע מהפקודה הקולית להפעיל פקודת מדיה במכשיר עם Assistant מובנית, קודם צריך להגדיר את פקודות המדיה הנתמכות שבהן בכוונתך לתמוך. לאחר מכן צריך לאכוף את הפקודות האלה על ידי הפעלת המאפיין CastReceiverOptions.enforceSupportedCommands
. ממשק המשתמש שולחי SDK של Cast ובמכשירים עם מסך מגע ישתנה כדי לשקף את ההגדרות האלה. אם הדגל לא מופעל, הפקודות הקוליות הנכנסות יופעלו.
לדוגמה, אם מאשרים את הגישה ל-PAUSE
מאפליקציות השליחה וממכשירים עם מסך מגע, צריך גם להגדיר את המקלט כך שישקף את ההגדרות האלה. אחרי ההגדרה, כל הפקודות הקוליות הנכנסות יוסרו אם הן לא ייכללו ברשימת הפקודות הנתמכות.
בדוגמה הבאה אנחנו מספקים את הערך CastReceiverOptions
בתחילת ה-CastReceiverContext
. הוספנו תמיכה בפקודה PAUSE
ואילצנו את הנגן לתמוך בפקודה הזו בלבד. עכשיו, אם פקודה קולית תבקש פעולה נוספת כמו SEEK
, הפעולה תידחה. המשתמש יקבל הודעה על כך שהפקודה עדיין לא נתמכת.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
אפשר להחיל לוגיקה נפרדת לכל פקודה שרוצים להגביל. מסירים את הדגל enforceSupportedCommands
, ועבור כל פקודה שרוצים להגביל אפשר ליירט את ההודעה הנכנסת. כאן אנחנו מעכבים את הבקשה שסופקה על ידי ה-SDK, כך שפקודות SEEK
שנשלחות למכשירים עם Assistant מובנית לא יפעילו חיפוש באפליקציה Web Acceptr.
בפקודות מדיה שהאפליקציה לא תומכת בהן, צריך להחזיר את הסיבה לשגיאה המתאימה, כמו NOT_SUPPORTED
.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
seekData => {
// Block seeking if the SEEK supported media command is disabled
if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
.INVALID_REQUEST);
e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
return e;
}
return seekData;
});
הפעלה ברקע מהפעילות הקולית
אם פלטפורמת Cast משמיעה את הצליל של האפליקציה שלך ברקע במסגרת פעילות של Assistant, כמו האזנה לדיבור של המשתמש או מענה לשיחה, הודעת FocusState
עם הערך NOT_IN_FOCUS
תישלח לאפליקציה Web Aware כשהפעילות תתחיל. הודעה נוספת עם IN_FOCUS
תישלח בסיום הפעילות.
בהתאם לאפליקציה שלכם ולמדיה שמופעלת, ייתכן שתרצו להשהות את המדיה כשה-FocusState
הוא NOT_IN_FOCUS
על ידי יירוט ההודעה FOCUS_STATE
.
לדוגמה, כדאי להשהות את ההפעלה של ספר האודיו אם Assistant מגיבה לשאילתה של משתמש, כדי לספק חוויית משתמש טובה.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
focusStateRequestData => {
// Pause content when the app is out of focus. Resume when focus is restored.
if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
playerManager.pause();
} else {
playerManager.play();
}
return focusStateRequestData;
});
שפת הכתוביות המוגדרת באמצעות הקול
אם משתמש לא מצהיר במפורש את שפת הכתוביות, השפה שבה יופיעו הכתוביות תהיה זהה לשפה שבה נאמרה הפקודה.
בתרחישים האלה, הפרמטר isSuggestedLanguage
של ההודעה הנכנסת מציין אם המשתמש הציע את השפה המשויכת או ביקש אותו באופן מפורש.
לדוגמה, הערך isSuggestedLanguage
מוגדר לערך true
בפקודה "Ok Google, turn on caption on", כי השפה נקבעה על סמך השפה שבה נאמרה הפקודה. אם השפה שמשתמשים ביקשו אותה באופן מפורש, למשל ב-"OK Google, Turn on lang caption", isSuggestedLanguage
תוגדר כ-false
.
מטא-נתונים והעברה של קול
אמנם הפקודות הקוליות מטופלות על ידי WebReceiver כברירת מחדל, אבל כדאי לוודא שהמטא-נתונים של התוכן מלאים ומדויקים. כך אפשר להבטיח שפקודות קוליות יטופלו כראוי על ידי Assistant ושהמטא-נתונים יצפו באופן תקין בסוגים חדשים של ממשקים, כמו אפליקציית Google Home ותצוגות חכמות כמו Google Home Hub.
העברת השידור
שימור מצב הסשן הוא הבסיס להעברת שידור. המשתמשים יכולים להעביר שידורים קיימים של אודיו ווידאו בין מכשירים באמצעות פקודות קוליות, אפליקציית Google Home או מסכים חכמים. המדיה מפסיקה לפעול במכשיר אחד (המקור) וממשיכה במכשיר אחר (היעד). כל מכשיר Cast עם הקושחה העדכנית ביותר יכול לשמש כמקורות או כיעדים בהעברת סטרימינג.
זרימת האירועים להעברת סטרימינג היא:
- במכשיר המקור:
- הפעלת המדיה נפסקת.
- האפליקציה WebReceiver מקבלת פקודה לשמור את מצב המדיה הנוכחי.
- האפליקציה 'מקלט האינטרנט' מושבתת.
- במכשיר היעד:
- האפליקציה WebReceiver נטענת.
- האפליקציה WebReceiver מקבלת פקודה שמשחזרת את מצב המדיה השמורה.
- הפעלת המדיה תמשיך.
הרכיבים של מצב המדיה כוללים:
- המיקום או חותמת הזמן הספציפיים של השיר, הסרטון או פריט המדיה.
- הוא יופיע בתור רחב יותר (למשל, פלייליסט או רדיו של אומן).
- המשתמש המאומת.
- מצב הפעלה (למשל, מופעל או מושהה).
מתבצעת הפעלה של העברת שידור
כדי להטמיע את העברת השידור עבור ה-Web Aware:
- מעדכנים את
supportedMediaCommands
באמצעות הפקודהSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- לחלופין, ניתן לשנות את מיירוטי ההודעות
SESSION_STATE
ו-RESUME_SESSION
כפי שמתואר במאמר שימור מצב הסשן. יש לבטל אותן רק אם צריך לאחסן נתונים מותאמים אישית כחלק מתמונת המצב של הסשן. אחרת, הטמעת ברירת המחדל לשימור מצבי סשנים תתמוך בהעברה בסטרימינג.
שימור מצב הסשן
ה-Web Acceptr SDK מספק הטמעת ברירת מחדל לאפליקציות של WebReceiver כדי לשמור את מצבי הסשן. לשם כך, מקבלים תמונת מצב של סטטוס המדיה הנוכחי, ממירים את הסטטוס לבקשת טעינה וממשיכים את הסשן עם בקשת הטעינה.
במקרה הצורך, אפשר לבטל את בקשת הטעינה שנוצרה על ידי Web Acceptr במיירט ההודעות של SESSION_STATE
. אם רוצים להוסיף נתונים מותאמים אישית לבקשת הטעינה, כדאי לשים אותם בתוך loadRequestData.customData
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.SESSION_STATE,
function (sessionState) {
// Override sessionState.loadRequestData if needed.
const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
sessionState.loadRequestData.credentials = newCredentials;
// Add custom data if needed.
sessionState.loadRequestData.customData = {
'membership': 'PREMIUM'
};
return sessionState;
});
אפשר לאחזר את הנתונים בהתאמה אישית מ-loadRequestData.customData
במיירט ההודעות RESUME_SESSION
.
let cred_ = null;
let membership_ = null;
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.RESUME_SESSION,
function (resumeSessionRequest) {
let sessionState = resumeSessionRequest.sessionState;
// Modify sessionState.loadRequestData if needed.
cred_ = sessionState.loadRequestData.credentials;
// Retrieve custom data.
membership_ = sessionState.loadRequestData.customData.membership;
return resumeSessionRequest;
});
טעינה מראש של תוכן
השירות 'מקלט האינטרנט' תומך בטעינה מראש של פריטי מדיה אחרי פריט ההפעלה הנוכחי בתור.
פעולת הטעינה מראש מורידה מראש כמה קטעים מהפריטים הקרובים. המפרט פועל בערך preloadTime באובייקט QueueItem (ברירת המחדל היא 20 שניות אם לא צוין). הזמן מבוטא בשניות, ביחס לסוף הפריט שמופעל עכשיו . רק ערכים חיוביים תקפים. לדוגמה, אם הערך הוא 10 שניות, הפריט הזה יטען מראש 10 שניות לפני שהפריט הקודם יסתיים. אם זמן הטעינה מראש גבוה יותר מהזמן שנותר לפריט הנוכחי, הטעינה מראש תתבצע בהקדם האפשרי. כך שאם צוין ערך גדול מאוד של טעינה מראש ב-QueueItem, אחד מהם יכול להשיג את ההשפעה בכל פעם שאנחנו מפעילים את הפריט הנוכחי, אנחנו כבר טוענים מראש את הפריט הבא. עם זאת, אנחנו משאירים למפתח את ההגדרה ואת הבחירה הזו, כי הערך הזה יכול להשפיע על רוחב הפס וביצועי הסטרימינג של הפריט הנוכחי שמופעל.
כברירת מחדל, הטעינה מראש תפעל עבור תוכן בסטרימינג בפורמט HLS, DASH ו'חלק'.
קובצי וידאו ואודיו רגילים בפורמט MP4, כמו MP3, לא ייטענו מראש, כי מכשירי Cast תומכים ברכיב מדיה אחד בלבד, ואי אפשר להשתמש בהם לטעינה מראש כשפריט תוכן קיים עדיין פועל.
הודעות בהתאמה אישית
חילופי הודעות היא שיטת האינטראקציה העיקרית עבור אפליקציות של Web Acceptr.
השולח מנפיק הודעות ל-WebReceiver באמצעות ממשקי ה-API של השולח (בפלטפורמה Android, iOS, Web). אובייקט האירוע (שהוא מניפסט של הודעה) שמועבר ל-event listener כולל רכיב נתונים (event.data
) שבו הנתונים מקבלים את המאפיינים של סוג האירוע הספציפי.
אפליקציה של Web Aware יכולה להאזין להודעות במרחב שמות מסוים. מעצם ידיעתו, פירוש הדבר שהאפליקציה Web Acceptr, תומכת בפרוטוקול הזה של מרחב השמות. לאחר מכן, כל שולחים מחוברים שרוצים לתקשר במרחב השמות הזה צריכים להשתמש בפרוטוקול המתאים.
כל מרחבי השמות מוגדרים על ידי מחרוזת וצריכים להתחיל ב-"urn:x-cast:
" ואחריה כל מחרוזת. לדוגמה,
"urn:x-cast:com.example.cast.mynamespace
".
זהו קטע קוד שבעזרתו המקבל יוכל להאזין להודעות מותאמות אישית משולחים מחוברים:
const context = cast.framework.CastReceiverContext.getInstance();
const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
// handle customEvent.
});
context.start();
באופן דומה, אפליקציות Web Acceptr יכולות לעדכן את השולחים לגבי מצב
ה-WebReceiver על ידי שליחת הודעות לשולחים מחוברים. אפליקציית Web Aware יכולה לשלוח הודעות באמצעות sendCustomMessage(namespace, senderId, message)
ב-CastReceiverContext
.
מקבל אינטרנט יכול לשלוח הודעות לשולח יחיד, בתגובה להודעה שהתקבלה או עקב שינוי במצב האפליקציה. נוסף על העברת הודעות מנקודה לנקודה (בהגבלה של עד 64kb), שרת האינטרנט יכול גם לשדר הודעות לכל השולחים המחוברים.
העברה (Cast) למכשירי אודיו
לקבלת תמיכה בהפעלה של אודיו בלבד, קראו את המדריך ל-Google Cast למכשירי אודיו.
ב-Android TV
בקטע הזה מוסבר איך Google Web Aware משתמש בקלט שלכם כהפעלה וכתאימות ל-Android TV.
שילוב האפליקציה עם השלט הרחוק
Google WebReceiver שפועל במכשיר Android TV מתרגם קלט מאמצעי הקלט של המכשיר (כלומר שלט רחוק להחזקה ביד) כהודעות הפעלת מדיה שהוגדרו עבור מרחב השמות של urn:x-cast:com.google.cast.media
, כפי שמתואר בהודעות על הפעלת מדיה. האפליקציה חייבת לתמוך בהודעות האלה כדי לשלוט בהפעלה של המדיה באפליקציה כדי לאפשר בקרת הפעלה בסיסית מקלט הבקרה של Android TV.
הנחיות בנושא תאימות ל-Android TV
ריכזנו כאן כמה המלצות ומכשולים נפוצים שכדאי להימנע מהם כדי לוודא שהאפליקציה שלכם תואמת ל-Android TV:
- חשוב לשים לב שמחרוזת סוכן המשתמש מכילה גם את "Android" וגם את "CrKey"; אתרים מסוימים עשויים להפנות אוטומטית לאתר שמיועד לנייד בלבד כי הם מזהים את התווית Android. אל תניחו ש-"Android" במחרוזת של סוכן המשתמש תמיד מצביע על משתמש בנייד.
- מקבץ המדיה של Android עשוי להשתמש ב-GZIP שקוף לאחזור נתונים. מוודאים שנתוני המדיה יכולים להגיב ל-
Accept-Encoding: gzip
. - ייתכן שאירועי מדיה מסוג HTML5 ב-Android TV יופעלו בתזמונים שונים מאשר ב-Chromecast. הפעולה הזו עשויה לחשוף בעיות שהוסתרו ב-Chromecast.
- כשמעדכנים את המדיה, צריך להשתמש באירועים שקשורים למדיה שהופעלו על ידי רכיבי
<audio>/<video>
, כמוtimeupdate
,pause
ו-waiting
. כדאי להימנע משימוש באירועים שקשורים לרשתות, כמוprogress
,suspend
ו-stalled
, כי הם בדרך כלל תלויים בפלטפורמה. למידע נוסף על טיפול באירועי מדיה במקלט, ראו את המאמר אירועי מדיה. - כשמגדירים את אישורי ה-HTTPS של האתר המקבל, חשוב לכלול אישורי CA מתווכים. כדי לוודא שנתיב האישור המהימן של האתר כולל אישור CA עם התווית 'הורדה נוספת', תוכלו לבדוק את דף בדיקת ה-SSL של Qualsys. יכול להיות שהוא לא יטען בפלטפורמות Android.
- דף המקבל מוצג על ידי Chromecast במישור גרפי של 720p, אבל פלטפורמות העברה אחרות, כולל Android TV, עשויות להציג את הדף עד 1080p. ודאו שקנה המידה של דף המקבל משתנה בחינניות ברזולוציות שונות.