הוספת תכונות ליבה למקלט האינטרנט המותאם אישית

הדף הזה מכיל קטעי קוד ותיאורים של התכונות הזמינות עבור אפליקציה מותאמת אישית של המקבל.

  1. רכיב cast-media-player שמייצג את ממשק המשתמש המובנה של הנגן סופקו באמצעות Web Acceptr.
  2. עיצוב מותאם אישית דמוי CSS לרכיב cast-media-player כדי לעצב מגוון סגנונות רכיבי ממשק משתמש כמו background-image, splash-image ו font-family
  3. רכיב סקריפט לטעינת ה-framework של Web תגובות.
  4. קוד JavaScript ליירוט הודעות ולטיפול באירועים.
  5. תור להפעלה אוטומטית.
  6. אפשרויות להגדרת ההפעלה.
  7. אפשרויות להגדרת ההקשר של המקלט האינטרנטי.
  8. אפשרויות להגדרת פקודות שנתמכות על ידי אפליקציית Web Acceptr.
  9. קריאת JavaScript להפעלת האפליקציה Web Acceptr.

אפשרויות תצורה של אפליקציה ואפשרויות

הגדרת האפליקציה

CastReceiverContext הוא המחלקה החיצונית ביותר שנחשפת למפתח, והוא מנהל את הטעינה של ספריות בסיסיות ומטפל באתחול של ה-SDK של WebReceiver. ה-SDK מספק ממשקי API שמאפשרים למפתחי אפליקציות להגדיר את ה-SDK באמצעות CastReceiverOptions ההגדרות האלה נבדקות פעם אחת בכל השקה של אפליקציה, ומועברים אל את ה-SDK בזמן ההגדרה של הפרמטר האופציונלי בקריאה start

הדוגמה הבאה מראה איך לעקוף את התנהגות ברירת המחדל כדי לזהות אם החיבור של השולח עדיין מחובר באופן פעיל. כאשר מקלט האינטרנט לא הצלחנו לתקשר עם שולח maxInactivity שניות, נשלח אירוע SENDER_DISCONNECTED. ההגדרות האישיות למטה מבטל את הזמן הקצוב הזה. האפשרות הזו יכולה להיות שימושית במהלך ניפוי באגים כי היא מונעת סגירת הסשן של הכלי לניפוי באגים מרחוק ב-Chrome אין שולחים מחוברים במצב IDLE.

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);

הגדרת הנגן

כשטוענים תוכן, ה-SDK של Web היעדים מאפשר להגדיר הפעלה משתנים כמו DRM מידע, להגדיר ניסיונות חוזרים ולבקש handlers באמצעות cast.framework.PlaybackConfig. המידע הזה מטופל על ידי PlayerManager ומוערך בזמן יצירת השחקנים. השחקנים נוצרים בכל פעם שמועברת טעינה חדשה ל-SDK של מקלט האינטרנט שינויים ב PlaybackConfig אחרי שהנגן נוצר, ההערכה של המשחק הבא תתבצע טעינת תוכן. ב-SDK אפשר למצוא את השיטות הבאות לשינוי ה-SDK PlaybackConfig

  • CastReceiverOptions.playbackConfig כדי לשנות את אפשרויות ברירת המחדל לתצורה במהלך האתחול CastReceiverContext
  • PlayerManager.getPlaybackConfig() כדי לקבל את ההגדרות הנוכחיות.
  • PlayerManager.setPlaybackConfig() כדי לשנות את ההגדרה הנוכחית. ההגדרה הזו חלה על כל טעינות נוספות או עד שהוא יבוטל שוב.
  • PlayerManager.setMediaPlaybackInfoHandler() להחיל הגדרות נוספות רק עבור פריט המדיה שנטען בו בחלק העליון של ההגדרות האישיות הנוכחיות. מתבצעת קריאה ל-handler בדיוק לפני השחקן במהלך היצירה. שינויים שיבוצעו כאן אינם קבועים ולא נכללים בשאילתות אל getPlaybackConfig(). כשפריט המדיה הבא נטען, ה-handler הזה נקראת שוב.

הדוגמה הבאה מראה איך להגדיר את PlaybackConfig כשמאתחלים את CastReceiverContext. ההגדרה מבטלת בקשות יוצאות עבור השגת מניפסטים. ה-handler מציין שבקשות CORS לבקרת גישה צריך להתבצע באמצעות פרטי כניסה כמו קובצי cookie או כותרות הרשאות.

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

הדוגמה הבאה מראה איך לעקוף את PlaybackConfig באמצעות getter ורכיב המפענח סופקו ב-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;
});

האזנה לאירועים

ה-SDK של Web Acceptr מאפשר לאפליקציה של מכשיר Web Acceptr לטפל באירועי שחקן. הפונקציה event listener לוקחת cast.framework.events.EventType פרמטר (או מערך של הפרמטרים האלה) שמציין את האירועים אמור להפעיל את המאזינים. מערכים מוגדרים מראש של אפשר למצוא 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
});

יירוט הודעה

ה-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();

טיפול בשגיאות

אם מתרחשות שגיאות בכלי ליירוט ההודעות, האפליקציה של מקלט האינטרנט אמורה לחזור מתאימה 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 של תוכן להפעלה (דומה לכתובת ה-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 כדי לקבל את יכולת המכשיר ל-enum הזה. הערכים של טיפוסים בני מנייה (enum) הם מוגדר ב cast.framework.system.DeviceCapabilities

הדוגמה הזו מראה אם המכשיר הרספונסיבי יכול להפעיל 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 Acceptr דרך השולח אפליקציות (באינטרנט, ב-Android וב-iOS), פקודות קוליות עם Assistant מובנית מכשירים, מקשי מגע במסכים חכמים ושלטים רחוקים ב-Android TV מכשירים. ערכת ה-SDK של Cast מספקת ממשקי API שונים שמאפשרים לאפליקציית האינטרנט לקבל גישה מטפלים באינטראקציות האלה, מעדכנים את ממשק המשתמש של האפליקציה באמצעות מצבי פעולה של משתמשים, ואם רוצים, לשלוח את השינויים כדי לעדכן שירותים לקצה העורפי.

פקודות מדיה נתמכות

מצבי הבקרה של ממשק המשתמש נקבעים לפי MediaStatus.supportedMediaCommands לבקרים מורחבים, למקלט ולשלט רחוק לשולחי iOS ו-Android אפליקציות שפועלות במכשירי מגע, ואפליקציות שפועלות במכשירי Android TV. כאשר Command ברמת הסיביות מופעלת בנכס, והלחצנים שקשורים לפעולה הזו מופעלים. אם הערך לא מוגדר, הלחצן הוא מושבת. אפשר לשנות את הערכים האלה במקלט האינטרנט על ידי:

  1. באמצעות PlayerManager.setSupportedMediaCommands כדי להגדיר Commands
  2. הוספת פקודה חדשה באמצעות addSupportedMediaCommands
  3. הסרת פקודה קיימת באמצעות 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;
}

פקודות קוליות

פקודות המדיה הבאות נתמכות כרגע ב-WebReceiver SDK עבור מכשירים עם Assistant מובנית. הטמעות ברירת המחדל של הפקודות האלה נמצא ב cast.framework.PlayerManager

פקודה תיאור
Play להפעיל או להמשיך את ההפעלה ממצב השהיה.
השהיה להשהות את ההפעלה של התוכן הנוכחי.
הקודם דילוג לפריט המדיה הקודם בתור המדיה.
הבא דילוג לפריט המדיה הבא בתור המדיה.
עצירה הפסקת המדיה שמופעלת כרגע.
ללא חזרה השבתת החזרה על פריטי מדיה בתור לאחר הפעלת הפריט האחרון בתור.
חזרה על יחיד חזרה על המדיה שמופעלת כרגע ללא הגבלת זמן.
חזרה על הכול חזרה על כל הפריטים בתור לאחר הפעלת הפריט האחרון בתור.
חזרה על הכול והשמעה אקראית כאשר תסתיים ההפעלה של הפריט האחרון בתור, השמעה אקראית של 'הבאים בתור' וחזרה על כל הפריטים בתור.
הפעלה אקראית ההשמעה אקראית של פריטי המדיה בתור המדיה שלך.
הפעלה או השבתה של כתוביות הפעלה / השבתה של כתוביות למדיה. האפשרות 'הפעלה / השבתה' זמינה גם לפי שפה.
דילוג לזמן המוחלט קופץ לזמן המוחלט שצוין.
הרצה לזמן ביחס לזמן הנוכחי דילוג קדימה או אחורה לפי פרק הזמן שצוין ביחס לזמן ההפעלה הנוכחי.
משחק שוב אפשר להפעיל מחדש את המדיה שפועלת כרגע או להפעיל את פריט המדיה האחרון שהופעל, אם לא מופעל כרגע תוכן.
הגדרת קצב ההפעלה שינוי קצב ההפעלה של המדיה. הפעולה הזו אמורה להתבצע כברירת מחדל. אפשר להשתמש בכלי ליירוט ההודעות SET_PLAYBACK_RATE כדי לבטל בקשות לקצב שליחת בקשות נכנסות.

פקודות מדיה נתמכות עם קול

כדי למנוע מפקודה קולית להפעיל פקודת מדיה ב-Assistant: מהמכשיר שלך, קודם צריך להגדיר פקודות מדיה נתמכות שאתם מתכוונים לתמוך בהם. לאחר מכן צריך לאכוף את הפקודות האלה על ידי הפעלת ה CastReceiverOptions.enforceSupportedCommands לנכס. ממשק המשתמש אצל שולחים של Cast SDK ומכשירים שתומכים במגע ישתנה ל- לשקף את התצורות האלה. אם הדגל לא מופעל, הקול הנכנס הפקודות יופעלו.

לדוגמה, אם תיתן אישור לאפליקציה 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 נשלחת לאפליקציה של מקלט האינטרנט כאשר הפעילות מתחילה. כשהפעילות תסתיים, נשלחת הודעה נוספת עם 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, הפעלת הכתוביות", כי השפה הסיקה הפקודה נאמרה. אם השפה נשלחה באופן מפורש, למשל בפקודה "OK Google, אני רוצה להפעיל את הכתוביות באנגלית, הערך של isSuggestedLanguage מוגדר ל-false.

מטא-נתונים והעברה קולית

למרות שפקודות קוליות מטופלות על ידי Web Acceptr כברירת מחדל, אתם צריכים לוודא שהמטא-נתונים של התוכן שלך מלאים ומדויקים. כך אפשר להבטיח בפקודות הקוליות מטפלים כראוי ב-Assistant ושהמטא-נתונים מוצג בצורה תקינה בסוגים חדשים של ממשקים, כמו אפליקציית Google Home, במסכים חכמים כמו Google Home Hub.

העברה בסטרימינג

שימור מצב הסשן הוא הבסיס להעברת השידור, המשתמשים יכולים להעביר שידורי אודיו ווידאו קיימים בין מכשירים באמצעות פקודות קוליות, Google Home אפליקציה או מסכים חכמים. המדיה מפסיקה לפעול במכשיר אחד (המקור) וממשיכה במכשיר אחר (המקור היעד). כל מכשיר Cast עם הקושחה האחרונה יכול לשמש כמקורות או יעדים העברה בסטרימינג.

תהליך העברת האירוע להעברת סטרימינג הוא:

  1. במכשיר המקור:
    1. המדיה מפסיקה לפעול.
    2. האפליקציה Web Gettingr מקבלת פקודה לשמור את המדיה הנוכחית state.
    3. האפליקציה Web Gettingr כבויה.
  2. במכשיר היעד:
    1. האפליקציה של מכשיר האינטרנט נטען.
    2. האפליקציה Web Acceptr מקבלת פקודה לשחזר את המדיה שנשמרה state.
    3. המדיה ממשיכה לפעול.

הרכיבים של מצב המדיה כוללים:

  • המיקום הספציפי או חותמת הזמן של השיר, הסרטון או פריט המדיה.
  • הוא יופיע בתור רחב יותר (למשל, פלייליסט או רדיו של אומן).
  • המשתמש המאומת.
  • מצב ההפעלה (לדוגמה: הפעלה או השהיה).

מתבצעת הפעלה של העברת סטרימינג

כדי להטמיע את העברת הסטרימינג עבור מקלט האינטרנט:

  1. עדכון הגרסה supportedMediaCommands באמצעות הפקודה STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. אפשר לשנות את ההודעה SESSION_STATE ו-RESUME_SESSION מכשירי יירוט כפי שמתואר בשימור סשן . צריך לשנות את ההגדרות האלה רק אם יש צורך בנתונים מותאמים אישית שיישמר כחלק מתמונת המצב של הסשן. אחרת, ברירת המחדל לשמירה על מצבי הפעילות של המשתמשים, יתמוך בהעברת השידור.

מצב הסשן נשמר

ה-SDK של מקלט האינטרנט מספק הטמעת ברירת מחדל לאפליקציות של מקלט האינטרנט לשמר את מצבי הסשן על ידי צילום תמונת מצב של סטטוס המדיה הנוכחי, את הסטטוס לבקשת טעינה, והמשך הסשן עם בקשת הטעינה.

ניתן לבטל את בקשת הטעינה שנוצרה על ידי מקלט האינטרנט כלי ליירוט ההודעות 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 תומכים ברכיב מדיה אחד בלבד ולא ניתן להשתמש בהם כדי לטעון מראש בזמן פריט התוכן הקיים עדיין מופעל.

הודעות בהתאמה אישית

חילופי הודעות היא שיטת האינטראקציה העיקרית לאפליקציות של מקלט אינטרנט.

שולח שולח הודעות למקבל אינטרנט באמצעות ממשקי ה-API של השולח עבור הפלטפורמה שבה השולח פועל (Android, iOS, אינטרנט). אובייקט האירוע (שהוא הוא הביטוי של הודעה) שמועברת למאזינים של האירוע רכיב נתונים (event.data) שבו הנתונים לוקחים את המאפיינים של סוג אירוע ספציפי.

אפליקציה של מקלט אינטרנט עשויה לבחור להאזין להודעות מרחב שמות. בעקבות זאת, נאמר שאפליקציית 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();

באופן דומה, אפליקציות של מקלט אינטרנט יכולות לעדכן את השולחים על המצב של מקבל האינטרנט על ידי שליחת הודעות לשולחים המחוברים. מקלט אינטרנט האפליקציה יכולה לשלוח הודעות באמצעות sendCustomMessage(namespace, senderId, message) על CastReceiverContext מקבל אינטרנט יכול לשלוח הודעות לשולח מסוים, בתגובה ל הודעה שהתקבלה או עקב שינוי במצב האפליקציה. מעבר מנקודה לנקודה הודעות (בהגבלה של 64kb), מקלט אינטרנט עשוי גם לשדר הודעות אל כל השולחים המחוברים.

הפעלת Cast להתקני אודיו

לתמיכה באודיו, אפשר לעיין במדריך של Google Cast להתקני אודיו הפעלה בלבד.

Android TV

הקטע הזה מתאר איך מקלט האינטרנט של Google משתמש בקלט שלכם בתור הפעלה, ותאימות ל-Android TV.

שילוב האפליקציה עם השלט הרחוק

מקלט האינטרנט של Google שפועל במכשיר Android TV מתרגם קלט מ אמצעי הקלט לשליטה במכשיר (כלומר שלט רחוק להחזקה ביד) בזמן הפעלת מדיה הודעות שהוגדרו למרחב השמות urn:x-cast:com.google.cast.media, כאשר שמתואר בהודעות להפעלת מדיה. שלך האפליקציה חייבת לתמוך בהודעות האלה כדי לשלוט במדיה של האפליקציה הפעלה כדי לאפשר שליטה בסיסית בהפעלה משליטה של Android TV של קלטים.

הנחיות לתאימות ל-Android TV

הנה כמה המלצות ומכשולים נפוצים שכדאי להימנע מהם כדי להבטיח האפליקציה שלכם תואמת ל-Android TV:

  • חשוב לשים לב שהמחרוזת של סוכן המשתמש מכילה גם את המילה "Android". ו-CrKey; אתרים מסוימים עשויים להפנות מחדש לאתר לנייד בלבד מפני שהם מזהים את Android התיוג. לא כדאי להניח ש-"Android" במחרוזת user-agent תמיד מציין משתמש בנייד.
  • מקבץ המדיה של Android עשוי להשתמש ב-GZIP שקוף לאחזור נתונים. כדאי לוודא נתוני המדיה שלך יכולים להגיב לAccept-Encoding: gzip.
  • ייתכן שאירועי מדיה בפורמט HTML5 ב-Android TV יופעלו בתזמונים שונים מאשר Chromecast. פעולה זו עשויה לחשוף בעיות שהוסתרו ב-Chromecast.
  • כשמעדכנים את המדיה, צריך להשתמש באירועים שקשורים למדיה שהופעלו על ידי <audio>/<video> כמו timeupdate, pause ו-waiting. נמנעים משימוש ברשתות אירועים קשורים כמו progress, suspend ו-stalled, כי הם בדרך כלל בהתאם לפלטפורמה. למידע על אירועי מדיה למידע נוסף על טיפול באירועי מדיה במקלט.
  • כשמגדירים את אישורי ה-HTTPS של האתר המקבל, חשוב לכלול אישורי CA ביניים. לצפייה דף בדיקת SSL מסוג Qualsys ל- לאמת: אם נתיב האישור המהימן של האתר שלך כולל רשות אישורים אישור עם התווית 'הורדה נוספת', אז יכול להיות שהוא לא ייטען על בסיס Android פלטפורמות שונות.
  • בעוד שדף המקבל מוצג ב-Chromecast במישור גרפיקה של 720p, בפלטפורמות Cast, כולל Android TV, יכול להיות שהדף יוצג ברזולוציה של עד 1080p. ודאו דף המקבל משתנה יפה ברזולוציות שונות.