Thiết lập bằng dịch vụ Nhóm DAI

Chọn nền tảng: HTML5 Android iOS tvOS Cast Roku

IMA SDK đơn giản hoá việc tích hợp quảng cáo đa phương tiện vào trang web và ứng dụng của bạn.

SDK IMA có thể yêu cầu quảng cáo từ bất kỳ máy chủ quảng cáo nào tuân thủ VAST và quản lý việc phát quảng cáo trong ứng dụng của bạn.

Với SDK IMA DAI, các ứng dụng sẽ gửi yêu cầu luồng cho video quảng cáo và nội dung cho nội dung VOD hoặc nội dung trực tiếp. Sau đó, SDK sẽ trả về một luồng video kết hợp để bạn không phải quản lý việc chuyển đổi giữa quảng cáo và video nội dung trong ứng dụng của mình.

Hướng dẫn này minh hoạ cách phát luồng Phân phát nhóm DAI bằng cách sử dụng IMA DAI SDK cho CAF.

Trước khi sử dụng hướng dẫn này, hãy làm quen với giao thức Trình nhận web của Khung ứng dụng Chromecast. Hướng dẫn này giả định rằng bạn đã hiểu cơ bản về các khái niệm của trình thu CAF, chẳng hạn như đối tượng trình chặn thông báo và mediaInformation, đồng thời đã quen thuộc với việc sử dụng Công cụ điều khiển và lệnh truyền để mô phỏng trình gửi CAF.

Để sử dụng tính năng Phân phát nhóm IMA DAI, bạn phải hợp tác với một đối tác Phân phát nhóm và phải có tài khoản Ad Manager 360 Nâng cao. Nếu bạn có tài khoản Ad Manager, hãy liên hệ với người quản lý tài khoản để biết thêm thông tin. Để biết thông tin về cách đăng ký Ad Manager, hãy truy cập vào Trung tâm trợ giúp Ad Manager.

Để biết thông tin về cách tích hợp với các nền tảng khác hoặc cách sử dụng SDK phía máy khách của IMA, hãy xem SDK quảng cáo trên phương tiện truyền thông tương tác.

Tổng quan về cơ chế Phân phát nhóm IMA DAI

Việc triển khai tính năng Phân phát nhóm bằng SDK DAI CAF IMA bao gồm hai thành phần chính, được minh hoạ trong hướng dẫn này:

  • StreamRequest: Một đối tượng xác định yêu cầu luồng đến máy chủ quảng cáo của Google. Yêu cầu chỉ định Mã mạng, Khoá thành phần tuỳ chỉnh và Khoá API không bắt buộc, cũng như các tham số không bắt buộc khác.
  • StreamManager: Một đối tượng xử lý hoạt động giao tiếp giữa luồng video và IMA DAI SDK, chẳng hạn như kích hoạt ping theo dõi và chuyển tiếp sự kiện luồng đến nhà xuất bản.

Điều kiện tiên quyết

  • Tài khoản Cast Developer Console có các thiết bị thử nghiệm đã đăng ký.
  • Một ứng dụng trình thu web được lưu trữ và đăng ký với Cast Developer Console, đồng thời có thể được sửa đổi để lưu trữ mã do hướng dẫn này cung cấp.
  • Một ứng dụng gửi được định cấu hình để sử dụng ứng dụng nhận web của bạn. Đối với ví dụ này, hãy sử dụng công cụ Lệnh và điều khiển của Cast làm ứng dụng gửi.

Định cấu hình đối tượng MediaInfo của người gửi

Trước tiên, hãy định cấu hình đối tượng MediaInfo của ứng dụng gửi để thêm các trường sau:

Trường Nội dung
contentId Giá trị nhận dạng riêng biệt cho mục nội dung nghe nhìn này.

CONTENT_ID

contentUrl Không bắt buộc. URL của luồng dự phòng để phát nếu không tải được luồng DAI.

BACKUP_STREAM_URL

contentType Không bắt buộc. Loại mime của luồng sao lưu nội dung. Chỉ cần thiết cho luồng DASH.

CONTENT_STREAM_MIMETYPE

streamType Chuỗi ký tự hoặc hằng số dùng cho giá trị này sẽ khác nhau tuỳ theo nền tảng của người gửi.
customData Trường customData chứa kho lưu trữ khoá-giá trị của các trường bắt buộc bổ sung. Trong mẫu này, tệp chứa các tham số luồng DAI của bạn. Trong một ứng dụng chính thức, bạn có thể truyền một giá trị nhận dạng mà ứng dụng nhận truyền của bạn sẽ sử dụng để truy xuất các tham số này bằng một yêu cầu phía máy chủ.
Trường Nội dung
daiStreamType Loại luồng DAI của bạn. "LIVE" hoặc "VOD"

DAI_STREAM_TYPE

networkCode Mã mạng cho tài khoản Google Ad Manager 360 của bạn.

NETWORK_CODE

customAssetKey Trường này chỉ cần thiết cho sự kiện phát trực tiếp. Khoá thành phần tuỳ chỉnh giúp xác định sự kiện Phân phát nhóm quảng cáo trong Google Ad Manager 360.

CUSTOM_ASSET_KEY

apiKey Khoá API không bắt buộc để truy xuất Mã luồng từ SDK IMA DAI.

API_KEY

Dưới đây là một số mã mẫu giúp bạn bắt đầu:

Web

Để định cấu hình các giá trị này trong trình gửi web của Cast, trước tiên, hãy tạo một đối tượng MediaInfo có dữ liệu bắt buộc, sau đó gửi yêu cầu tải đến trình nhận web.

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

Để định cấu hình các giá trị này trong trình gửi web của Cast, trước tiên, hãy tạo một đối tượng MediaInfo có dữ liệu bắt buộc, sau đó gửi yêu cầu tải đến trình nhận web.

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)

Để định cấu hình các giá trị này trong trình gửi web của Cast, trước tiên, hãy tạo một đối tượng GCKMediaInformation có dữ liệu bắt buộc, sau đó gửi yêu cầu tải đến trình nhận web.

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)

Để định cấu hình các giá trị này trong trình gửi web của Cast, trước tiên, hãy tạo một đối tượng GCKMediaInformation có dữ liệu bắt buộc, sau đó gửi yêu cầu tải đến trình nhận web.

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
}

Công cụ CAC

Để định cấu hình các giá trị này trong công cụ Lệnh và điều khiển truyền, hãy nhấp vào thẻ Tải nội dung nghe nhìn rồi đặt loại yêu cầu tải tuỳ chỉnh thành LOAD. Sau đó, thay thế dữ liệu JSON trong vùng văn bản bằng JSON này:

{
  "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"
    }
  }
}

Bạn có thể gửi yêu cầu tải tuỳ chỉnh này đến trình nhận để kiểm tra các bước còn lại.

Tạo một trình thu CAF cơ bản

Tạo trình thu nhận web tuỳ chỉnh, như trong Hướng dẫn về trình thu nhận web tuỳ chỉnh của CAF SDK.

Mã của trình thu nhận sẽ có dạng như sau:

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

Nhập IMA DAI SDK và tải Trình quản lý trình phát

Thêm thẻ tập lệnh để nhập IMA DAI SDK cho CAF vào trình thu nhận web, ngay sau tập lệnh tải CAF. Trong thẻ tập lệnh, hãy lưu trữ bối cảnh của trình nhận và trình quản lý trình phát dưới dạng hằng số trước khi khởi động trình nhận.

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

Khởi chạy Trình quản lý luồng IMA

Khởi chạy Trình quản lý luồng 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>

Tạo Trình chặn tải của Trình quản lý luồng

Trước khi các mục nội dung nghe nhìn được chuyển đến CAF, hãy tạo yêu cầu về luồng trong trình chặn thông báo 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();

Tạo yêu cầu luồng

Hoàn tất hàm createStreamRequest để tạo luồng Phân phát nhóm dựa trên yêu cầu tải 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;
    };

Truy xuất tệp kê khai được ghép từ VTP của bạn

Nếu yêu cầu luồng của bạn thành công, hãy sử dụng streamManager.getStreamId() để truy xuất mã nhận dạng của luồng. Đối tác kỹ thuật video (VTP) hoặc trình thao tác tệp kê khai tuỳ chỉnh của bạn sẽ cung cấp hướng dẫn để truy xuất URL tệp kê khai bằng cách sử dụng mã luồng này.

Sau khi bạn truy xuất URL tệp kê khai, hãy thay thế contentUrl hiện có bằng manifestUrl mới.

Cuối cùng, trước khi trả về tệp kê khai luồng đã sửa đổi, hãy gọi phương thức loadStreamMetadata trên streamManager để thông báo cho IMA SDK rằng SDK này có thể yêu cầu siêu dữ liệu luồng một cách an toàn. Lệnh gọi này chỉ cần thiết cho các luồng 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;
          });
    };

Dọn dẹp các thành phần IMA DAI

Khi bạn đã hoàn tất thành công việc yêu cầu và hiển thị quảng cáo trong một luồng Phân phát nhóm quảng cáo bằng IMA DAI SDK, bạn nên dọn dẹp mọi tài nguyên sau khi phiên Phân phát nhóm quảng cáo hoàn tất. Gọi StreamManager.destroy() để dừng phát trực tuyến, dừng tất cả hoạt động theo dõi quảng cáo và giải phóng tất cả thành phần luồng đã tải.