开始使用 IMA DAI SDK

选择您感兴趣的 DAI 解决方案

广告连播投放 DAI

IMA SDK 可简化将多媒体广告集成到网站和应用中的过程。

IMA SDK 可以通过 符合 VAST 规定 广告服务器,以及管理应用中的广告播放。

借助 IMA DAI SDK,应用会针对 无论是视频点播还是直播内容然后,SDK 会返回组合的视频流, 让您不必管理在应用程序内的广告和内容视频之间的切换 应用。

本指南将演示如何使用 IMA DAI SDK for CAF。

在使用本指南之前,请先熟悉 Chromecast 应用框架的 Web 接收器 协议。本指南假定您对 CAF 接收器概念有基本的了解, 例如 消息拦截器mediaInformation 对象,并且熟悉如何使用 Cast 命令和控制工具、 模拟 CAF 发送器。

要使用 IMA DAI 广告连播投放,您必须与广告连播投放合作伙伴合作 必须具有 Ad Manager 360 高级课程 。如果您有 Ad Manager 账号,请联系您的客户经理 。有关注册 Ad Manager 的信息,请访问 Ad Manager 帮助中心

有关与其他平台集成或使用 IMA 客户端 SDK,请参阅互动式媒体广告 SDK

IMA DAI Pod Serving 概览

使用 IMA CAF DAI SDK 实施广告连播投放涉及两个主要组件: 具体说明如下:

  • StreamRequest: 用于定义向 Google 广告服务器的视频流请求的对象。 请求会指定网络代码、自定义资产密钥和可选的 API 密钥 以及其他可选参数
  • StreamManager: 用于处理视频流与 IMA DAI 之间的通信的对象 例如触发跟踪 ping,以及将视频流事件转发到 发布商。

前提条件

  • 拥有满足以下条件的 Cast Developer Console 账号: 已注册的测试设备。
  • 托管网络接收器 应用 您在 Cast Developer Console 中注册过,并且此扩展程序可以进行修改,以便托管 本指南提供的代码
  • 配置为使用您的网页接收器应用的发送应用。对于 在此示例中,请使用 Cast 命令和控件 工具作为您的发件人。

配置发送者的 MediaInfo 对象

首先,配置发送者应用的 MediaInfo 对象 包含以下字段:

字段 目录
contentId 此媒体项的唯一标识符。

CONTENT_ID

contentUrl 可选。在 DAI 视频流加载失败时要播放的备用视频流网址。

BACKUP_STREAM_URL

contentType 可选。内容备用视频流的 MIME 类型。仅 DASH 需要 数据流

CONTENT_STREAM_MIMETYPE

streamType 用于此值的字符串字面量或常量因发件人而异 平台。
customData customData 字段包含 必填字段。
字段 目录
manifestUrl 由您的清单操纵器或第三方提供的视频流网址 合作伙伴。它应该会要求您插入 IMA DAI SDK。在此示例中,清单网址 它包含占位符 [[STREAMID]],该占位符已替换为 然后再发出请求。

MANIFEST_URL

networkCode 您的 Google Ad Manager 360 账号的广告资源网代码。

NETWORK_CODE

customAssetKey 用于标识 Google Ads 中的广告连播投放事件的自定义素材资源键 Manager 360。在某些情况下,您可以从清单中获取此属性 或第三方 Pod 投放合作伙伴。

CUSTOM_ASSET_KEY

apiKey 用于从 IMA DAI SDK 检索视频流 ID 的可选 API 密钥。

API_KEY

以下是一些可帮助您上手的代码示例:

Web

要在 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 的 IMA DAI SDK 导入您的网页接收器, 在脚本加载 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 视频流管理器

初始化 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>

创建数据流管理器加载拦截器

在将媒体项传递到 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 投放流的数据流 。

    /**
     * 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 应用请求和播放 Pod 传送的视频流 框架和 IMA DAI SDK for CAF。