הגדרה באמצעות שירות Pod DAI

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

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

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

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

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

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

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

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

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

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

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

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

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

הגדרת האובייקטים של 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 פקודות ואמצעי בקרה, לוחצים על הכרטיסייה 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>

יצירת ה-Load Interceptor של Stream Manager

לפני שקובצי המדיה מועברים ל-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

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