開始使用 IMA DAI SDK

選取所需的 DAI 解決方案

廣告連播放送 DAI

IMA SDK 可簡化將多媒體廣告整合至網站和應用程式的流程。

IMA SDK 可以從任何符合 VAST 規定的廣告伺服器請求廣告,並管理應用程式中的廣告播放作業。

應用程式會使用 IMA DAI SDK,為 VOD 或直播內容發出廣告和內容影片的串流請求。接著,SDK 會傳回合併的影片串流,因此你不必在應用程式中切換廣告和內容影片的方式。

本指南示範如何使用適用於 CAF 的 IMA DAI SDK,播放即時 DAI 廣告連播放送串流。

開始使用本指南前,請先熟悉 Chromecast 應用程式架構的 Web Receiver 通訊協定。本指南假設您對 CAF 接收器概念 (例如訊息攔截器mediaInformation 物件) 有基本的瞭解,並且熟悉使用 Cast 指令與控制工具來模擬 CAF 傳送者。

如要使用 IMA DAI 廣告連播放送功能,您必須與廣告連播放送合作夥伴合作,並擁有 Ad Manager 360 Advanced 帳戶。如果您有 Ad Manager 帳戶,請與客戶經理聯絡以瞭解詳情。若要瞭解如何申請 Ad Manager,請前往 Ad Manager 說明中心

如要瞭解如何整合其他平台,或瞭解如何使用 IMA 用戶端 SDK,請參閱「互動式媒體廣告 SDK」一文。

IMA DAI 廣告連播放送總覽

使用 IMA CAF DAI SDK 導入廣告連播放送時,必須涵蓋兩個主要元件,詳情請參閱本指南:

  • StreamRequest:這個物件可定義傳送至 Google 廣告伺服器的串流要求。要求會指定網路代碼、自訂資產金鑰和選用的 API 金鑰,以及其他選用參數。
  • StreamManager:這個物件會處理影片串流與 IMA DAI SDK 之間的通訊,例如觸發追蹤連線偵測 (ping),以及將串流事件轉送至發布商。

先備知識

設定傳送者的 MediaInfo 物件

首先,設定傳送端應用程式的 MediaInfo 物件,加入下列欄位:

欄位 目錄
contentId 此媒體項目的專屬 ID。

CONTENT_ID

contentUrl 選用設定。如果 DAI 串流無法載入,要播放的備份串流網址。

BACKUP_STREAM_URL

contentType 選用設定。內容備份串流的 Mime 類型。只有 DASH 串流需要。

CONTENT_STREAM_MIMETYPE

streamType 此值使用的字串常值或常數,會因傳送端平台而異。
customData customData 欄位含有其他必填欄位的鍵/值儲存庫。
欄位 目錄
manifestUrl 資訊清單操縱器或第三方合作夥伴提供的影片串流網址。在提出要求之前,您應該插入 IMA DAI SDK 提供的串流 ID。在這個範例中,資訊清單網址包含預留位置 [[STREAMID]]。在提出要求之前,系統會將這個預留位置替換成串流 ID。

MANIFEST_URL

networkCode Google Ad Manager 360 帳戶的聯播網代碼。

NETWORK_CODE

customAssetKey 自訂素材資源鍵,用來識別 Google Ad Manager 360 中的廣告連播放送事件。在某些情況下,您可以從資訊清單操縱器或第三方 Pod 放送合作夥伴取得這項資訊。

CUSTOM_ASSET_KEY

apiKey (選用) 用來從 IMA DAI SDK 擷取串流 ID 的 API 金鑰。

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 = {
manifestUrl: "MANIFEST_URL",
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("manifestUrl", "MANIFEST_URL")
  .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 = @{
  @"manifestUrl": @"MANIFEST_URL",
  @"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 = [
  "liveConfigID": "MANIFEST_URL",
  "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": {
      "liveConfigID": "MANIFEST_URL",
      "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 並取得播放器管理工具

新增指令碼代碼,在指令碼載入 CAF 之後,將 CAF 適用的 IMA DAI SDK 匯入您的網路接收器。在指令碼標記中,在啟動接收器之前,將接收器結構定義和玩家管理員儲存為常數。

<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>

建立串流管理員載入攔截器

將媒體項目傳遞至 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 函式,根據 CAF 載入要求建立 Pod 供應串流。

    /**
     * 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 streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
      const customData = castRequest.media.customData;

      streamRequest.customAssetKey = customData.customAssetKey;
      streamRequest.networkCode = customData.networkCode;
      streamRequest.apiKey = customData.apiKey;

      return streamRequest;
    };

將內容網址替換成資訊清單網址和串流 ID

如果串流要求成功,請使用 streamManager.getStreamId() 擷取串流 ID 並插入 manifestUrl 中 (請替換 [[STREAMID]])。接著,將現有的 contentUrl 替換為新的 manifestUrl,讓 CAF 使用拼接的廣告連播播放直播。

    /**
     * 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.');
            const media = castRequestWithPodStreamData.media;
                const manifestUrl = media.customData.manifestUrl || "";
                if (manifestUrl) {
                    console.log('Replacing the contentURL with the manifest URL and stream ID');
                    const streamId = streamManager.getStreamId();
                    castRequestWithPodStreamData.media.contentUrl = manifestUrl.replace('[[STREAMID]]', streamId);

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

您現在可以使用 Cast 應用程式架構,以及 CAF 適用的 IMA DAI SDK 來請求及播放返回廣告連播放送串流。