תחילת העבודה עם IMA DAI SDK

בחירת פתרון ה-DAI הרצוי

Pod Serving DAI

ערכות ה-SDK של IMA מאפשרות לכם לשלב בקלות מודעות מולטימדיה באתרים ובאפליקציות שלכם.

ערכות IMA SDK יכולות לבקש מודעות מכל שרת מודעות שתואם ל-VAST ולנהל את ההפעלה של המודעות באפליקציות.

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

במדריך הזה מוסבר איך להפעיל שידור של מודעות DAI ב-Pod, באמצעות IMA DAI SDK ל-CAF.

לפני שמשתמשים במדריך הזה, כדאי להכיר את הפרוטוקול של Web Receiver של Chromecast Application Framework. הנחת המוצא במדריך הזה היא שיש לכם הבנה בסיסית במושגים של מקבלי CAF, כמו מחסומים להודעות ואובייקטים מסוג mediaInformation, ושהכרתם את השימוש בכלי הבקרה והפיקוד של Cast כדי לדמות שולחים של CAF.

כדי להשתמש בהצגת מודעות ברצף ב-IMA DAI, עליכם לעבוד עם שותף להצגת מודעות ברצף, ועליכם להיות בעלי חשבון Ad Manager 360 מתקדם. אם יש לכם חשבון Ad Manager, תוכלו לפנות למנהל החשבון לקבלת פרטים נוספים. מידע נוסף על ההרשמה ל-Ad Manager זמין במרכז העזרה של Ad Manager.

מידע על שילוב עם פלטפורמות אחרות או על שימוש ב-SDK של IMA בצד הלקוח זמין במאמר ערכות SDK של מודעות Interactive Media.

סקירה כללית על הצגת מודעות ב-IMA DAI Pod

כדי להטמיע הצגת מודעות במודול באמצעות IMA CAF DAI SDK, צריך להשתמש בשני רכיבים עיקריים, שמתוארים במדריך הזה:

  • StreamRequest: אובייקט שמגדיר בקשת סטרימינג לשרתים של Google לפרסום. בבקשות מצוינים קוד רשת, מפתח נכס מותאם אישית ומפתח API אופציונלי, וגם פרמטרים אופציונליים אחרים.
  • StreamManager: אובייקט שמטפל בתקשורת בין מקור הווידאו ל-IMA DAI SDK, למשל הפעלת פינגים למעקב והעברת אירועי מקור לבעלים של אתר החדשות.

דרישות מוקדמות

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

הגדרת אובייקטי MediaInfo של השולח

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

שדה תוכן עניינים
contentId מזהה ייחודי של פריט המדיה הזה.

CONTENT_ID

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

BACKUP_STREAM_URL

contentType זה שינוי אופציונלי. ה-MIME type של מקורות נתוני הגיבוי של התוכן. האפשרות הזו נדרשת רק לשידורי DASH.

CONTENT_STREAM_MIMETYPE

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

DAI_STREAM_TYPE

networkCode קוד הרשת של חשבון Google Ad Manager 360.

NETWORK_CODE

customAssetKey השדה הזה נדרש רק לשידורים חיים. מפתח הנכס המותאם אישית שמזהה את אירוע הצגת המודעות של רצף המודעות ב-Google Ad Manager 360.

CUSTOM_ASSET_KEY

apiKey מפתח API אופציונלי לאחזור מזהה של מקור נתונים מ-IMA DAI SDK.

API_KEY

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

פיתוח אתרים

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

// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "CONTENT_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
  daiStreamType: "DAI_STREAM_TYPE",
  networkCode: "NETWORK-CODE",
  customAssetKey: "CUSTOM_ASSET_KEY",
  apiKey: "API_KEY"
};

// 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("daiStreamType", "DAI_STREAM_TYPE")
  .put("networkCode", "NETWORK-CODE")
  .put("customAssetKey", "CUSTOM_ASSET_KEY")
  .put("apiKey", "API_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
  .setContentUrl("BACKUP_STREAM_URL")
  .setContentType("CONTENT_STREAM_MIMETYPE")
  .setStreamType(MediaInfo.STREAM_TYPE_LIVE)
  .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 = @{
  @"daiStreamType": @"DAI_STREAM_TYPE",
  @"networkCode": @"NETWORK-CODE",
  @"customAssetKey": @"CUSTOM_ASSET_KEY",
  @"apiKey": @"API_KEY"};
mediaInfoBuilder.customData = customData;

GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
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 = [
  "daiStreamType": "DAI_STREAM_TYPE",
  "networkCode": "NETWORK-CODE",
  "customAssetKey": "CUSTOM_ASSET_KEY",
  "region": "API_KEY"
]

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
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, לוחצים על הכרטיסייה Load Media (טעינה של מדיה) ומגדירים את סוג הבקשה המותאם אישית לטעינה כ-LOAD. לאחר מכן מחליפים את נתוני ה-JSON באזור הטקסט ב-JSON הזה:

{
  "media": {
    "contentId": "CONTENT_ID",
    "contentUrl": "BACKUP_STREAM_URL",
    "contentType": ""CONTENT_STREAM_MIMETYPE"",
    "streamType": "LIVE",
    "customData": {
      "daiStreamType": "DAI_STREAM_TYPE",
      "networkCode": "NETWORK-CODE",
      "customAssetKey": "CUSTOM_ASSET_KEY",
      "oAuthToken": "API_KEY"
    }
  }
}

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

יצירת מקלט CAF בסיסי

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

הקוד של הנמען אמור להיראות כך:

<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>
    // ...
  </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 livestream request object for a Pod Serving stream.
     * @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((castRequestWithPodStreamData) => {
            console.log('Successfully made DAI stream request.');
            // ...
            return castRequestWithPodStreamData;
          })
          .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 כדי ליצור סטרימינג של Pod Serving על סמך בקשת הטעינה של CAF.

    /**
     * Creates a livestream request object for a Pod Serving stream.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => {
      const customData = castRequest.media.customData;
      let streamRequest;
      if (customData.daiStreamType == "LIVE") {
        streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
        streamRequest.customAssetKey = customData.customAssetKey;
        streamRequest.networkCode = customData.networkCode;
        streamRequest.apiKey = customData.apiKey;
      } else if (customData.daiStreamType == "VOD") {
        streamRequest = new google.ima.cast.dai.api.PodVodStreamRequest();
        streamRequest.networkCode = customData.networkCode;
        streamRequest.apiKey = customData.apiKey;
      }
      return streamRequest;
    };

אחזור המניפסט המחובר מה-VTP

אם הבקשה להפעלת הסטרימינג תאושר, תוכלו להשתמש ב-streamManager.getStreamId() כדי לאחזר את המזהה של הסטרימינג. שותף הטכנולוגיה של הסרטונים (VTP) או הכלי להתאמה אישית של קובצי מניפסט יספק הוראות לאחזור כתובת URL של מניפסט באמצעות מזהה הסטרימינג הזה.

אחרי שאתם מאחזרים את כתובת ה-URL של המניפסט, מחליפים את contentUrl הקיים ב-manifestUrl החדש.

לבסוף, לפני שמחזירים את מניפסט הסטרימינג שעבר שינוי, צריך להפעיל את השיטה loadStreamMetadata ב-streamManager כדי להודיע ל-IMA SDK שהוא יכול לבקש בבטחה מטא-נתונים של סטרימינג. הקריאה הזו נדרשת רק לשידורי VOD.

    /**
     * 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((castRequestWithPodStreamData) => {
            console.log('Successfully made DAI stream request.');

            // This is a sample VTP integration. Consult your VTP documentation
            // for how to retrieve an ad-stitched stream manifest URL.
            const manifestTemplate = "https://.../manifest.m3u8?gam_stream_id=[[STREAMID]]";
            const streamId = streamManager.getStreamId();
            const manifestUrl = manifestTemplate.replace('[[STREAMID]]', streamId)
            // Assign your manifestUrl to the request's content URL.
            castRequestWithPodStreamData.media.contentUrl = manifestUrl;

            // After generating the manifest URL, VOD streams must notify the
            // IMA SDK that it is safe to request ad pod metadata.
            // This is only necessary for VOD streams. It is a no-op for
            // livestreams, so no conditional is needed.
            streamManager.loadStreamMetadata();

            return castRequestWithPodStreamData;
          })
          .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;
          });
    };

עכשיו אפשר לבקש ולנגן שידורים של Pod Serving באמצעות Cast Application Framework ו-IMA DAI SDK ל-CAF.