Настройка IMA SDK для DAI

Выберите интересующее вас решение DAI

Обслуживание капсул DAI

Пакеты IMA SDK упрощают интеграцию мультимедийной рекламы на ваши веб-сайты и в приложения.

Пакеты SDK IMA могут запрашивать рекламу с любого совместимого с VAST сервера объявлений и управлять воспроизведением рекламы в ваших приложениях.

С помощью IMA DAI SDK приложения запрашивают потоковое видео с рекламой и контентом для VOD или прямых трансляций. Затем SDK возвращает объединённый видеопоток, поэтому вам не придётся переключаться между рекламой и контентом в приложении.

В этом руководстве показано, как воспроизводить поток DAI Pod Serving с использованием IMA DAI SDK для CAF.

Перед использованием этого руководства ознакомьтесь с протоколом веб-приёмника Chromecast Application Framework . Данное руководство предполагает наличие базовых знаний о приёмниках CAF, таких как перехватчики сообщений и объекты mediaInformation , а также умение использовать инструмент Cast Command and Control для эмуляции отправителя CAF.

Чтобы использовать IMA DAI Pod Serving, необходимо работать с партнёром по Pod Serving и иметь расширенную учётную запись Ad Manager 360. Если у вас есть учётная запись Ad Manager, обратитесь к своему менеджеру аккаунта для получения дополнительной информации. Информацию о регистрации в Ad Manager можно найти в справочном центре Ad Manager .

Информацию об интеграции с другими платформами или об использовании клиентских SDK IMA см. в разделе Interactive Media Ads SDKs .

Обзор обслуживания IMA DAI Pod

Реализация Pod Serving с использованием IMA CAF DAI SDK включает два основных компонента, которые продемонстрированы в этом руководстве:

  • StreamRequest : объект, определяющий потоковый запрос к рекламным серверам Google. В запросах указываются сетевой код, пользовательский ключ ресурса и необязательный ключ API, а также другие необязательные параметры.
  • StreamManager : объект, который обрабатывает связь между видеопотоком и IMA DAI SDK, например, отправляет пинги отслеживания и пересылает события потока издателю.

Предпосылки

  • Учетная запись Cast Developer Console с зарегистрированными тестовыми устройствами.
  • Размещенное приложение веб-приемника , зарегистрированное в консоли разработчика Cast и которое можно изменить для размещения кода, предоставленного этим руководством.
  • Отправляющее приложение, настроенное на использование вашего веб-приёмника. В этом примере в качестве отправителя используйте инструмент 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. В производственном приложении вместо этого можно передать идентификатор, который ваше приложение-приёмник будет использовать для получения этих параметров с помощью запроса на стороне сервера.
Поле Содержание
daiStreamType Тип вашей трансляции DAI. Один из вариантов: "LIVE" или "VOD"

DAI_STREAM_TYPE

networkCode Сетевой код вашего аккаунта Google Ad Manager 360.

NETWORK_CODE

customAssetKey Это поле необходимо только для прямых трансляций. Ключ пользовательского ресурса, идентифицирующий событие Pod Serving в 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); });

Андроид

Чтобы настроить эти значения в веб-отправителе 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 , перейдите на вкладку «Загрузить медиа» и выберите тип запроса на загрузку «ЗАГРУЗИТЬ». Затем замените 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

Добавьте тег script для импорта IMA DAI SDK для CAF в веб-приёмник сразу после загрузки CAF скриптом. В теге script сохраните контекст приёмника и менеджер проигрывателя как константы перед запуском приёмника.

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

Создайте перехватчик нагрузки 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 на основе запроса на загрузку 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() , чтобы остановить воспроизведение потока, остановить всё отслеживание рекламы и освободить все загруженные ресурсы потока.