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

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

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

Подающий DAI

В этом руководстве показано, как воспроизводить поток DAI Pod Serving для живого или VOD-контента, используя IMA DAI SDK для HTML5 с видеоплеером, который использует hls.js для воспроизведения. Чтобы просмотреть или следовать завершенному примеру интеграции с поддержкой как HLS.js, так и Safari Playback, см . пример HLS Pod Serving . Для поддержки DASH.js см. пример DASH Pod Serving . Вы можете загрузить эти примеры приложений со страницы релиза HTML5 DAI GitHub .

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

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

  • PodStreamRequest / PodVodStreamRequest : объект, который определяет запрос потока к рекламным серверам Google. Запросы указывают Network Code , а PodStreamRequest также требует Custom Asset Key и необязательный API key . Оба включают другие необязательные параметры.

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

Предпосылки

Прежде чем начать, вам понадобится следующее:

  • Три пустых файла:

    • dai.html
    • dai.css
    • dai.js
  • Python, установленный на вашем компьютере, веб-сервере или другой размещенной среде разработки для использования в тестировании

Настройте среду разработки

Поскольку SDK загружает зависимости, используя тот же протокол, что и страница, с которой он загружается, вам нужно использовать веб-сервер для тестирования вашего приложения. Быстрый способ запустить локальный сервер разработки — использовать встроенный сервер Python.

  1. Используя командную строку, из каталога, содержащего ваш файл index.html , выполните:

    python -m http.server 8000
  2. В веб-браузере перейдите по адресу http://localhost:8000/

    Вы также можете использовать любую другую размещенную среду разработки или веб-сервер, например Apache HTTP Server .

Создать видеоплеер

Сначала измените dai.html , чтобы создать элемент HTML5 video и div для использования в элементах Ad UI. Также добавьте необходимые теги для загрузки файлов dai.css и dai.js , а также для импорта видеоплеера hls.js

Затем измените dai.css , чтобы указать размер и положение элементов страницы. Наконец, в dai.js определите переменные для хранения информации о запросе потока и функцию initPlayer() для запуска при загрузке страницы.

Константы запроса потока следующие:

  • BACKUP_STREAM : URL-адрес резервного потока для воспроизведения в случае возникновения фатальной ошибки в процессе показа рекламы.

  • STREAM_URL : используется только для прямых трансляций . URL-адрес видеопотока, предоставленный вашим манипулятором манифеста или сторонним партнером, использующим Pod Serving. Он должен потребовать от вас вставить идентификатор потока, предоставленный IMA DAI SDK, перед тем, как вы сделаете запрос. В этом случае URL-адрес потока включает заполнитель [[STREAMID]] , который заменяется на идентификатор потока перед тем, как сделать запрос.

  • NETWORK_CODE : сетевой код для вашего аккаунта Ad Manager 360.

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

  • API_KEY : Используется только для прямых трансляций . Необязательный ключ API, который может потребоваться для получения идентификатора потока из IMA DAI SDK.

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
  <h2>IMA DAI SDK Demo (HLS.JS)</h2>
    <video id="video"></video>
    <div id="adUi"></div>
</body>
</html>

dai.css

#video,
#adUi {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0;
}

#adUi {
  cursor: pointer;
}

dai.js

var BACKUP_STREAM =
    'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'

// Stream Config.
const STREAM_URL = "";
const NETWORK_CODE = "";
const CUSTOM_ASSET_KEY = "";
const API_KEY = "";

var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
}

Загрузите IMA DAI SDK

Затем добавьте фреймворк DAI с помощью тега script в dai.html перед тегом dai.js.

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
...

Инициализируйте StreamManager и сделайте запрос на прямую трансляцию или VOD-трансляцию.

Обслуживание Pod в режиме реального времени

Чтобы запросить набор объявлений, создайте ima.dai.api.StreamManager , который отвечает за запрос и управление потоками DAI. Конструктор принимает элемент видео, а полученный экземпляр принимает элемент пользовательского интерфейса рекламы для обработки взаимодействий с рекламой.

Затем определите функцию для запроса прямой трансляции Pod Serving. Эта функция сначала создает PodStreamRequest , настраивает его с параметрами streamRequest, предоставленными на шаге 2, а затем вызывает streamManager.requestStream() с этим объектом запроса.

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  requestLivePodStream(NETWORK_CODE, CUSTOM_ASSET_KEY, API_KEY);
}

function requestLivePodStream(networkCode, customAssetKey, apiKey) {
  // clear HLS.js instance, if in use
  if (hls) {
    hls.destroy();
  }

  // Generate a Pod Serving live Stream Request
  const streamRequest = new google.ima.dai.api.PodStreamRequest();
  streamRequest.networkCode = networkCode;
  streamRequest.customAssetKey = customAssetKey;
  streamRequest.apiKey = apiKey;
  streamRequest.format = 'hls';
  streamManager.requestStream(streamRequest);
}

Обслуживание VOD Pod

Чтобы запросить набор объявлений, создайте ima.dai.api.StreamManager , который отвечает за запрос и управление потоками DAI. Конструктор принимает элемент видео, а полученный экземпляр принимает элемент пользовательского интерфейса рекламы для обработки взаимодействий с рекламой.

Затем определите функцию для запроса потока Pod Serving VOD. Эта функция сначала создает PodVodStreamRequest , настраивает его с параметрами streamRequest , предоставленными на шаге 2, а затем вызывает streamManager.requestStream() с этим объектом запроса.

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  requestVodPodStream(NETWORK_CODE);
}

function requestVodPodStream(networkCode) {
  // clear HLS.js instance, if in use
  if (hls) {
    hls.destroy();
  }

  // Generate a Pod Serving VOD Stream Request
  const streamRequest = new google.ima.dai.api.PodVodStreamRequest();
  streamRequest.networkCode = networkCode;
  streamRequest.format = 'hls';
  streamManager.requestStream(streamRequest);
}

Обработка событий потока

Обслуживание Pod в режиме реального времени

Далее реализуйте прослушиватели событий для основных видеособытий. Этот пример обрабатывает события STREAM_INITIALIZED , ERROR , AD_BREAK_STARTED и AD_BREAK_ENDED путем вызова функции onStreamEvent() . Эта функция обрабатывает загрузку потока и ошибки, а также отключает элементы управления проигрывателем во время воспроизведения рекламы, что требуется SDK. Когда поток загружен, видеоплеер загружает и воспроизводит предоставленный URL с помощью функции loadStream() .

dai.js

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  
  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
    google.ima.dai.api.StreamEvent.Type.ERROR,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
      console.log('Stream initialized');
      loadStream(e.getStreamData().streamId);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadStream('');
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

function loadStream(streamID) {
  var url;
  if(streamID) {
    url = STREAM_URL.replace('[[STREAMID]]', streamID);
  } else {
    console.log('Stream Initialization Failed');
    url = BACKUP_STREAM;
  }
  console.log('Loading:' + url);
  hls.loadSource(url);
  hls.attachMedia(videoElement);
}

Обслуживание VOD Pod

Далее реализуйте прослушиватели событий для основных видеособытий. Этот пример обрабатывает события STREAM_INITIALIZED , LOADED , ERROR , AD_BREAK_STARTED и AD_BREAK_ENDED путем вызова функции onStreamEvent() . Эта функция обрабатывает загрузку потока и ошибки, а также отключает элементы управления проигрывателем во время воспроизведения рекламы, что требуется SDK.

Кроме того, потоки VOD Pod Serving требуют вызова StreamManager.loadStreamMetadata() в ответ на событие STREAM_INITIALIZED . Вам также необходимо запросить URL потока у вашего партнера по видеотехнологиям (VTP). После успешного вызова loadStreamMetadata() он запускает событие LOADED , где вам следует вызвать функцию loadStream() с URL вашего потока для загрузки и воспроизведения потока.

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  
  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
    google.ima.dai.api.StreamEvent.Type.ERROR,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
    google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
      const streamId = e.getStreamData().streamId;
      // 'vtpInterface' is a place holder for your own video technology
      //  partner (VTP) API calls.
      vtpInterface.requestStreamURL({
        'streamId': streamId,
      })
      .then( (vtpStreamUrl) => {
        streamUrl = vtpStreamUrl;
        streamManager.loadStreamMetadata();
      }, (error) => {
        // Handle the error.
      });
      break;
    case google.ima.dai.api.StreamEvent.Type.LOADED:
      loadStream(streamUrl);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadStream();
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

function loadStream(url) {
  if(url) {
    console.log('Loading:' + url);
    hls.loadSource(url);
  } else {
    console.log('Stream Initialization Failed');
    hls.loadSource(BACKUP_STREAM);
  }
  hls.attachMedia(videoElement);
}

Обработка метаданных потока

На этом этапе вы реализуете прослушиватели событий для метаданных, чтобы уведомлять SDK о событиях рекламы. Прослушивание событий метаданных в потоке может различаться в зависимости от формата потока (HLS или DASH), типа потока (прямой или VOD-поток), типа вашего проигрывателя и типа используемого бэкэнда DAI. Для получения дополнительной информации см. наше руководство по временным метаданным .

Формат потока HLS (прямые трансляции и трансляции по запросу, проигрыватель HLS.js)

Если вы используете проигрыватель HLS.js , прослушивайте событие HLS.js FRAG_PARSING_METADATA , чтобы получить метаданные ID3 и передать их в SDK с помощью StreamManager.processMetadata() .

Чтобы автоматически воспроизвести видео после того, как все загружено и готово, прослушивайте событие HLS.js MANIFEST_PARSED , чтобы запустить воспроизведение.

function loadStream(streamID) {
  hls.loadSource(url);
  hls.attachMedia(videoElement);
  
  // Timed metadata is passed HLS stream events to the streamManager.
  hls.on(Hls.Events.FRAG_PARSING_METADATA, parseID3Events);
  hls.on(Hls.Events.MANIFEST_PARSED, startPlayback);
}

function parseID3Events(event, data) {
  if (streamManager && data) {
    // For each ID3 tag in the metadata, pass in the type - ID3, the
    // tag data (a byte array), and the presentation timestamp (PTS).
    data.samples.forEach((sample) => {
      streamManager.processMetadata('ID3', sample.data, sample.pts);
    });
  }
}

function startPlayback() {
  console.log('Video Play');
  videoElement.play();
}

DASH.js (формат потоков DASH, тип потоковой передачи Live и VOD)

Если вы используете проигрыватель DASH.js , вам придется использовать разные строки для прослушивания метаданных ID3 для потоков Live или VOD:

  • Прямые трансляции: 'https://developer.apple.com/streaming/emsg-id3'
  • Потоки VOD: 'urn:google:dai:2018'

Передайте метаданные ID3 в SDK с помощью StreamManager.processMetadata() .

Чтобы автоматически отобразить элементы управления видео после того, как все загружено и готово, прослушивайте событие DASH.js MANIFEST_LOADED .

const googleLiveSchema = 'https://developer.apple.com/streaming/emsg-id3';
const googleVodSchema = 'urn:google:dai:2018';
dashPlayer.on(googleLiveSchema, processMetadata);
dashPlayer.on(googleVodSchema, processMetadata);
dashPlayer.on(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);

function processMetadata(metadataEvent) {
  const messageData = metadataEvent.event.messageData;
  const timestamp = metadataEvent.event.calculatedPresentationTime;

  // Use StreamManager.processMetadata() if your video player provides raw
  // ID3 tags, as with dash.js.
  streamManager.processMetadata('ID3', messageData, timestamp);
}

function loadlistener() {
  showControls();

  // This listener must be removed, otherwise it triggers as addional
  // manifests are loaded. The manifest is loaded once for the content,
  // but additional manifests are loaded for upcoming ad breaks.
  dashPlayer.off(dashjs.MediaPlayer.events.MANIFEST_LOADED, loadlistener);
}

Shaka Player с прямыми трансляциями (формат потоков DASH)

Если вы используете проигрыватель Shaka для воспроизведения прямой трансляции, используйте строку 'emsg' для прослушивания событий метаданных. Затем используйте данные сообщения о событии в вашем вызове StreamManager.onTimedMetadata() .

shakaPlayer.addEventListener('emsg', (event) => onEmsgEvent(event));

function onEmsgEvent(metadataEvent) {
  // Use StreamManager.onTimedMetadata() if your video player provides
  // processed metadata, as with Shaka player livestreams.
  streamManager.onTimedMetadata({'TXXX': metadataEvent.detail.messageData});
}

Shaka Player с потоками VOD (формат потоков DASH)

Если вы используете проигрыватель Shaka для воспроизведения потока VOD, используйте строку 'timelineregionenter' для прослушивания событий метаданных. Затем используйте данные сообщения о событии в вашем вызове StreamManager.processMetadata() со строкой 'urn:google:dai:2018' .

shakaPlayer.addEventListener('timelineregionenter', (event) => onTimelineEvent(event));

function onTimelineEvent(metadataEvent) {
  const detail = metadataEvent.detail;
  if ( detail.eventElement.attributes &&
       detail.eventElement.attributes['messageData'] &&
       detail.eventElement.attributes['messageData'].value ) {
        const mediaId = detail.eventElement.attributes['messageData'].value;
        const pts = detail.startTime;
        // Use StreamManager.processMetadata() if your video player provides raw
        // ID3 tags, as with Shaka player VOD streams.
        streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
       }
}

Обработка событий игрока

Добавьте прослушиватели событий к событиям pause и start элемента видео, чтобы пользователь мог возобновить воспроизведение, когда SDK останавливается во время рекламных пауз.

function loadStream(streamUrl) {
  ...
  
  videoElement.addEventListener('pause', onStreamPause);
  videoElement.addEventListener('play', onStreamPlay);
}

function onStreamPause() {
  console.log('paused');
  if (isAdBreak) {
    videoElement.controls = true;
    adUiElement.style.display = 'none';
  }
}

function onStreamPlay() {
  console.log('played');
  if (isAdBreak) {
    videoElement.controls = false;
    adUiElement.style.display = 'block';
  }
}

Очистите активы IMA DAI

После успешного завершения запроса и отображения рекламы в потоке Pod Serving с помощью IMA DAI SDK мы рекомендуем вам очистить все ресурсы после завершения сеанса Pod Serving. Вызовите StreamManager.destroy() , чтобы остановить воспроизведение потока, остановить все отслеживание рекламы и освободить все загруженные потоковые активы.

Чтобы узнать о более продвинутых функциях SDK, ознакомьтесь с другими руководствами или примерами на GitHub .