הגדרת IMA SDK ל-DAI

בחירת פלטפורמה: HTML5 Android iOS tvOS Cast Roku

בחירת פתרון DAI שמעניין אתכם

הצגת DAI ב-Pod

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

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

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

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

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

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

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

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

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

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

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

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

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

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

CONTENT_ID

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

BACKUP_STREAM_URL

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

CONTENT_STREAM_MIMETYPE

streamType המחרוזת המילולית או הקבוע שמשמשים לערך הזה משתנים בהתאם לפלטפורמת השולח.
customData השדה customData מכיל מאגר של צמדי מפתח/ערך של שדות חובה נוספים. בדוגמה הזו, הוא מכיל את הפרמטרים של הזרם ב-DAI. באפליקציה לייצור, אפשר להעביר במקום זאת מזהה שאפליקציית מקלט Cast תשתמש בו כדי לאחזר את הפרמטרים האלה באמצעות בקשה בצד השרת.
שדה תוכן עניינים
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 Command and Control, לוחצים על הכרטיסייה 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 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>
    // ...
  </script>
</body>
</html>

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

מוסיפים תג script כדי לייבא את 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.

<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;
          });
    };

מחיקה של נכסי IMA DAI

אחרי שמסיימים בהצלחה את הבקשה וההצגה של מודעות בסטרימינג של Pod Serving באמצעות IMA DAI SDK, מומלץ לנקות את כל המשאבים אחרי שמסיימים את הסשן של Pod Serving. מתקשרים אל StreamManager.destroy() כדי להפסיק את ההפעלה של הסטרימינג, להפסיק את כל המעקב אחר מודעות ולבטל את כל נכסי הסטרימינג שנטענו.