שימוש ב-IMA DAI SDK ב-Chromecast

הפעלת סטרימינג של VOD שנרשם ב-Google Cloud Video Stitcher API

במדריך הזה נדגים איך להשתמש ב-IMA DAI SDK for CAF Web Receivers כדי לבקש ולהפעיל סשן של סטרימינג VOD ב-Google Cloud.

המדריך הזה מרחיב את הדוגמה הבסיסית מ-DAI עם שירות מלא, ומוסיף תמיכה בסטרימינג שנרשם ב-Google Cloud Video Stitcher API.

לפני שממשיכים, חשוב לוודא שפורמט הסטרימינג נתמך על ידי מקלטי אינטרנט של CAF.

למידע על שילוב עם פלטפורמות אחרות או על שימוש ב-IMA SDKs בצד הלקוח, אפשר לעיין במאמר בנושא Interactive Media Ads SDKs.

רקע

לפני שמשתמשים במדריך הזה, כדאי להכיר את הפרוטוקול של Web Receiver ב-Chromecast Application Framework.

המדריך הזה מיועד למי שיש לו ידע בסיסי במושגים של מקלטי CAF, כמו message interceptors, אובייקטים של MediaInformation ושימוש בכלי Cast Command and Control כדי לבצע אמולציה של שולח CAF.

רכיבים וארכיטקטורה של אפליקציות

הטמעה של הפעלת סטרימינג של VOD באמצעות Google Cloud Video Stitcher API עם IMA CAF DAI SDK כוללת שני רכיבים עיקריים, כפי שמוצג במדריך הזה:

  • ‫VideoStitcherVodStreamRequest: אובייקט שמגדיר בקשה להזרמת נתונים לשרתים של Google.
  • ‫StreamManager: אובייקט שמטפל בתקשורת בין סטרימינג הווידאו לבין IMA DAI SDK, כמו הפעלת פינגים למעקב והעברת אירועים של סטרימינג אל בעל האתר.

הגדרת פרויקט ב-Google Cloud

מזינים את המשתנים הבאים לשימוש ב-IMA SDK:

  • ‫Location (מיקום) – האזור ב-Google Cloud שבו נוצרה ההגדרה של ה-VOD.

    LOCATION

  • מספר הפרויקט: מספר הפרויקט בענן של Google שבו נעשה שימוש ב-Video Stitcher API.

    PROJECT_NUMBER

  • אסימון OAuth: אסימון OAuth לטווח קצר של חשבון שירות עם תפקיד המשתמש Video Stitcher. מידע נוסף על יצירת פרטי כניסה לטווח קצר לחשבונות שירות

    OAUTH_TOKEN

  • קוד הרשת: קוד הרשת של Google Ad Manager לשליחת בקשות להצגת מודעות.

    NETWORK_CODE

  • מזהה ההגדרה של VOD – מזהה ההגדרה של VOD לסטרימינג של VOD.

    VOD_CONFIG_ID

    מידע נוסף על יצירת מזהה הגדרות VOD זמין במדריך Cloud stitching create a VOD config.

    VOD_URI

הגדרת מכשיר מקבל Cast בהתאמה אישית

כדי לפתח מקלט Cast מותאם אישית, צריך את הדברים הבאים:

  • חשבון ב-Cast Developer Console עם מכשירי בדיקה ברשימת ההיתרים.

  • אפליקציית מקלט אינטרנט מתארחת שרשומה ב-Cast Developer Console, שאפשר לשנות אותה כדי לארח את הקוד שמופיע במדריך הזה.

  • אפליקציה לשליחה שהוגדרה לשימוש באפליקציית המקלט באינטרנט. לצורך הדוגמה הזו, במדריך הזה נעשה שימוש בכלי Cast Command and Control בתור השולח.

הכנת השולח להעברת נתוני הזרם אל המקלט

קודם כול, צריך להגדיר את אפליקציית השולח כך שתשלח בקשת טעינה למקלט האינטרנט, שתכלול את השדות הבאים באובייקט MediaInformation של הפלטפורמה.

שדה תוכן עניינים
contentId מזהה ייחודי של פריט המדיה הזה, כפי שמוגדר במסמכי העיון של Cast. אסור להשתמש באותו מזהה לכמה פריטים באותה רשימת השמעה של מדיה.

CONTENT_ID

contentUrl כתובת URL אופציונלית של שידור לגיבוי, שתופעל אם השידור של DAI לא ייטען.

BACKUP_STREAM_URL

contentType ‫Mimetype אופציונלי של כתובת ה-URL של הגיבוי של השידור להפעלה אם השידור של DAI לא נטען.

BACKUP_STREAM_MIMETYPE

streamType המחרוזת המילולית או הקבוע שמשמשים לערך הזה משתנים בהתאם לפלטפורמת השולח.

VOD

customData

השדה customData מכיל מאגר של צמדי מפתח/ערך של שדות חובה נוספים. במקרה הזה, customData מכיל את נתוני הסטרימינג של DAI שאספתם.

שדה תוכן עניינים
region LOCATION
projectNumber PROJECT_NUMBER
oAuthToken OAUTH_TOKEN
networkCode NETWORK_CODE
vodConfigId VOD_CONFIG_ID

ריכזנו כאן כמה דוגמאות לקוד שיעזרו לכם להתחיל:

אינטרנט

כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט MediaInfo עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.

// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "BACKUP_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.VOD;
mediaInfo.customData = {
  region: "LOCATION",
  projectNumber: "PROJECT_NUMBER",
  oAuthToken: "OAUTH_TOKEN",
  networkCode: "NETWORK_CODE",
  vodConfigId: "VOD_CONFIG_ID"
};

// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  () => { console.log('Load succeed'); },
  (errorCode) => { console.log('Error code: ' + errorCode); });

Android

כדי להגדיר את הערכים האלה בשולח אינטרנט של Cast, קודם יוצרים אובייקט MediaInfo עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.

JSONObject customData = new JSONObject()
  .put("region", "LOCATION")
  .put("projectNumber", "PROJECT_NUMBER")
  .put("oAuthToken", "OAUTH_TOKEN")
  .put("networkCode", "NETWORK_CODE")
  .put("vodConfigId", "VOD_CONFIG_ID");

MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
  .setContentUrl("BACKUP_STREAM_URL")
  .setContentType("BACKUP_STREAM_MIMETYPE")
  .setStreamType(MediaInfo.STREAM_TYPE_VOD)
  .setCustomData(customData)
  .build();

RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());

‫iOS ‏ (Obj-C)

כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט GCKMediaInformation עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.

NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
  @"region": @"LOCATION",
  @"projectNumber": @"PROJECT_NUMBER",
  @"oAuthToken": @"OAUTH_TOKEN",
  @"networkCode": @"NETWORK_CODE",
  @"vodConfigId": @"VOD_CONFIG_ID"
};

GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"BACKUP_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeNone;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];

GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
  request.delegate = self;
}

‫iOS (Swift)

כדי להגדיר את הערכים האלה בשולט Cast באינטרנט, קודם יוצרים אובייקט GCKMediaInformation עם הנתונים הנדרשים, ואז שולחים בקשת טעינה למקלט האינטרנט.

let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
  print("invalid mediaURL")
  return
}

let customData = [
  "region": "LOCATION",
  "projectNumber": "PROJECT_NUMBER",
  "oAuthToken": "OAUTH_TOKEN",
  "networkCode": "NETWORK_CODE",
  "vodConfigId": "VOD_CONFIG_ID"
]

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = "BACKUP_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.none
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()

guard let mediaInfo = mediaInformation else {
  print("invalid mediaInformation")
  return
}

if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) {
  request.delegate = self
}

כלי CAC

כדי להגדיר את הערכים האלה בכלי Cast Command and Control, לוחצים על הכרטיסייה Load Media (טעינת מדיה) ומגדירים את סוג בקשת הטעינה המותאמת אישית ל-LOAD. אחר כך מחליפים את נתוני ה-JSON באזור הטקסט ב-JSON הזה:

{
  "media": {
    "contentId": "CONTENT_ID",
    "contentUrl": "BACKUP_STREAM_URL",
    "contentType": "BACKUP_STREAM_MIMETYPE",
    "streamType": "VOD",
    "customData": {
      "region": "LOCATION",
      "projectNumber": "PROJECT_NUMBER",
      "oAuthToken": "OAUTH_TOKEN",
      "networkCode": "NETWORK_CODE",
      "vodConfigId": "VOD_CONFIG_ID"
    }
  }
}

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

יצירת מקלט אינטרנט CAF בהתאמה אישית

יוצרים מקלט אינטרנט בהתאמה אישית, כמו שמוסבר במדריך בנושא CAF SDK Custom Web Receiver.

הקוד של המקלט צריך להיראות כך:

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
  </script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance()
    castContext.start();
  </script>
</body>
</html>

ייבוא של IMA DAI SDK והשגת Player Manager

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

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();

    castContext.start();
  </script>
</body>
</html>

הפעלת IMA Stream Manager

מאתחלים את IMA Stream Manager.

<html>
<head>
  <script type="text/javascript"
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    castContext.start();
  </script>
</body>
</html>

יצירת Stream Manager Load Interceptor

לפני שהפריטים של המדיה מועברים ל-CAF, צריך ליצור את בקשת הסטרימינג ביירוט של הודעת LOAD.

    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    /**
     * Creates a VOD stream request object for the Video Stitcher API.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => { /* ... */};

    /**
     * Initates a DAI stream request for the final stream manifest.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
     */
    const createDAICastRequest = (castRequest) => {
        return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
          .then((castRequestWithStreamData) => {
            console.log('Successfully made DAI stream request.');
            return castRequestWithStreamData;
          })
          .catch((error) => {
            console.log('Failed to make DAI stream request.');
            // CAF will automatically fallback to the content URL
            // that it can read from the castRequest object.
            return castRequest;
          });
    };

    playerManager.setMessageInterceptor(
        cast.framework.messages.MessageType.LOAD, createDAICastRequest);

    castContext.start();

יצירת בקשת הזרמה

משלימים את הפונקציה createStreamRequest כדי ליצור בקשת סטרימינג של VOD ב-Video Stitcher API, על סמך בקשת הטעינה של CAF.

    /**
     * Creates a VOD stream request object for the Video Stitcher API.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => {
      const streamRequest = new google.ima.cast.dai.api.VideoStitcherVodStreamRequest();
      const customData = castRequest.media.customData;

      streamRequest.region = customData.region;
      streamRequest.projectNumber = customData.projectNumber;
      streamRequest.oAuthToken = customData.oAuthToken;
      streamRequest.networkCode = customData.networkCode;
      streamRequest.vodConfigId = customData.vodConfigId;
      streamRequest.videoStitcherSessionOptions = {};

      return streamRequest;
    };

(אופציונלי) הוספת אפשרויות של סשן סטרימינג

אפשר להתאים אישית את בקשת הסטרימינג על ידי הוספת אפשרויות הפעלה כדי לשנות את הגדרת ברירת המחדל של Cloud Video Stitcher API באמצעות VideoStitcherVodStreamRequest.videoStitcherSessionOptions. אם תספקו אפשרות לא מזוהה, Cloud Video Stitcher API יגיב עם שגיאת HTTP 400. אפשר לקבל עזרה במדריך לפתרון בעיות.

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

...

// The following session options are examples. Use session options
// that are compatible with your video stream.
streamRequest.videoStitcherSessionOptions = {
  "manifestOptions": {
    "bitrateOrder": "ascending"
  }
};

streamManager.requestStream(streamRequest);