Configura el SDK de IMA para la DAI

Los SDKs de IMA facilitan la integración de anuncios multimedia en tus sitios web y aplicaciones. Los SDKs de IMA pueden solicitar anuncios de cualquier servidor de anuncios compatible con VAST y administrar la reproducción de anuncios en tus aplicaciones. Con los SDKs de IMA DAI, las apps realizan una solicitud de transmisión para el video del anuncio y el contenido, ya sea VOD o contenido en vivo. Luego, el SDK devuelve una transmisión de video combinada, de modo que no tengas que administrar el cambio entre el anuncio y el video de contenido en tu app.

Selecciona la solución de DAI que te interesa

Publicación de grupos de anuncios de DAI

En esta guía, se muestra cómo reproducir una transmisión de Publicación de grupos de anuncios de DAI para contenido en vivo o VOD con el SDK de IMA DAI para HTML5 y un reproductor de video que depende de hls.js para la reproducción. Para ver o seguir una integración de muestra completa, con compatibilidad para HLS.js y reproducción en Safari, consulta el ejemplo de entrega de Pod de HLS. Para obtener información sobre la compatibilidad con DASH.js, consulta el ejemplo de DASH Pod Serving. Puedes descargar estas apps de ejemplo desde la página de versiones de GitHub de DAI en HTML5.

Descripción general de la Publicación de grupos de anuncios de DAI

La implementación de la publicación de Pods con el SDK de IMA de DAI implica dos componentes principales, que se demuestran en esta guía:

  • PodStreamRequest / PodVodStreamRequest: Es un objeto que define una solicitud de transmisión a los servidores de publicidad de Google. Las solicitudes especifican un código de red, y el objeto PodStreamRequest también requiere una clave de recurso personalizada y una clave de API opcional. Ambos incluyen otros parámetros opcionales.

  • StreamManager: Es un objeto que controla la comunicación entre la transmisión de video y el SDK de DAI de IMA, como el envío de pings de seguimiento y el reenvío de eventos de transmisión al publicador.

Requisitos previos

Antes de comenzar, necesitas lo siguiente:

  • Tres archivos vacíos:

    • dai.html
    • dai.css
    • dai.js
  • Python instalado en tu computadora, o un servidor web o algún otro entorno de desarrollo alojado para usar en las pruebas

Configura un entorno de desarrollo

Dado que el SDK carga las dependencias con el mismo protocolo que la página desde la que se carga, debes usar un servidor web para probar tu app. Una forma rápida de iniciar un servidor de desarrollo local es usar el servidor integrado de Python.

  1. Con una línea de comandos, desde el directorio que contiene tu archivo index.html, ejecuta lo siguiente:

    python -m http.server 8000
  2. En un navegador web, ve a http://localhost:8000/.

    También puedes usar cualquier otro servidor web o entorno de desarrollo alojado, como el servidor HTTP de Apache.

Crea un reproductor de video

Primero, modifica dai.html para crear un elemento de video HTML5 y un div para usarlo en los elementos de la IU del anuncio. También agrega las etiquetas necesarias para cargar los archivos dai.css y dai.js, así como para importar el reproductor de video hls.js.

Luego, modifica dai.css para especificar el tamaño y la posición de los elementos de la página. Por último, en dai.js, define variables para contener la información de la solicitud de transmisión y una función initPlayer() para ejecutar cuando se cargue la página.

Las constantes de la solicitud de transmisión son las siguientes:

  • BACKUP_STREAM: Es la URL de una transmisión de copia de seguridad para reproducir en caso de que el proceso de anuncios encuentre un error irrecuperable.

  • STREAM_URL: Solo se usa para transmisiones en vivo. Es la URL de transmisión de video que proporciona tu manipulador de manifiestos o socio externo que usa la Publicación de grupos de anuncios. Debería solicitarte que insertes el ID de transmisión que proporciona el SDK de IMA DAI antes de que realices una solicitud. En este caso, la URL de transmisión incluye un marcador de posición, [[STREAMID]], que se reemplaza por el ID de transmisión antes de realizar una solicitud.

  • NETWORK_CODE: Es el código de red de tu cuenta de Ad Manager 360.

  • CUSTOM_ASSET_KEY: Solo se usa para transmisiones en vivo. Es la clave del recurso personalizada que identifica tu evento de Publicación de Pods en Ad Manager 360. Tu manipulador de manifiestos o socio externo de Publicación de grupos de anuncios pueden crear este objeto.

  • API_KEY: Solo se usa para transmisiones en vivo. Es una clave de API opcional que puede ser necesaria para recuperar un ID de transmisión del SDK de IMA DAI.

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

Carga el SDK de IMA DAI

A continuación, agrega el framework de la DAI con una etiqueta de secuencia de comandos en dai.html, antes de la etiqueta de 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>
...

Inicializa StreamManager y realiza una solicitud de transmisión en vivo o de VOD

Publicación de pods de transmisiones en vivo

Para solicitar un conjunto de anuncios, crea un objeto ima.dai.api.StreamManager, que es responsable de solicitar y administrar transmisiones de DAI. El constructor toma un elemento de video y la instancia resultante toma un elemento de la IU del anuncio para controlar las interacciones con el anuncio.

Luego, define una función para solicitar la transmisión en vivo de Pod Serving. Esta función primero crea un PodStreamRequest, lo configura con los parámetros de streamRequest proporcionados en el paso 2 y, luego, llama a streamManager.requestStream() con ese objeto de solicitud.

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

Publicación de grupos de anuncios de VOD

Para solicitar un conjunto de anuncios, crea un objeto ima.dai.api.StreamManager, que es responsable de solicitar y administrar transmisiones de DAI. El constructor toma un elemento de video y la instancia resultante toma un elemento de la IU del anuncio para controlar las interacciones con el anuncio.

Luego, define una función para solicitar la transmisión de VOD de Pod Serving. Esta función primero crea un PodVodStreamRequest, lo configura con los parámetros de streamRequest proporcionados en el paso 2 y, luego, llama a streamManager.requestStream() con ese objeto de solicitud.

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

Cómo controlar eventos de transmisión

Publicación de pods de transmisiones en vivo

A continuación, implementa objetos de escucha de eventos para los eventos de video principales. En este ejemplo, se controlan los eventos STREAM_INITIALIZED, ERROR, AD_BREAK_STARTED y AD_BREAK_ENDED llamando a una función onStreamEvent(). Esta función controla la carga y los errores de la transmisión, además de inhabilitar los controles del reproductor mientras se reproduce un anuncio, lo que requiere el SDK. Cuando se carga la transmisión, el reproductor de video carga y reproduce la URL proporcionada con una función 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);
}

Publicación de grupos de anuncios de VOD

A continuación, implementa objetos de escucha de eventos para los eventos de video principales. En este ejemplo, se controlan los eventos STREAM_INITIALIZED, LOADED, ERROR, AD_BREAK_STARTED y AD_BREAK_ENDED llamando a una función onStreamEvent(). Esta función controla la carga y los errores de la transmisión, además de inhabilitar los controles del reproductor mientras se reproduce un anuncio, lo que requiere el SDK.

Además, las transmisiones de VOD Pod Serving requieren que se llame a StreamManager.loadStreamMetadata() en respuesta al evento STREAM_INITIALIZED. También debes solicitar una URL de transmisión a tu socio de tecnología de video (VTP). Una vez que la llamada a loadStreamMetadata() se realiza correctamente, se activa un evento LOADED, en el que debes llamar a una función loadStream() con la URL de tu transmisión para cargarla y reproducirla.

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

Cómo controlar los metadatos de la transmisión

En este paso, implementarás agentes de escucha de eventos para los metadatos y notificarás al SDK cuando ocurran eventos de anuncios. La escucha de eventos de metadatos intercalados puede variar según el formato de la transmisión (HLS o DASH), el tipo de transmisión (transmisión en vivo o VOD), el tipo de reproductor y el tipo de backend de DAI que se utilice. Para obtener más información, consulta nuestra guía de Metadatos Temporizados.

Formato de transmisión HLS (transmisiones en vivo y VOD, reproductor HLS.js)

Si usas un reproductor HLS.js, escucha el evento FRAG_PARSING_METADATA de HLS.js para obtener metadatos ID3 y pasarlos al SDK con StreamManager.processMetadata().

Para reproducir automáticamente el video después de que todo se haya cargado y esté listo, escucha el evento MANIFEST_PARSED de HLS.js para activar la reproducción.

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 (formato de transmisiones DASH, tipo de transmisión en vivo y VOD)

Si usas un reproductor DASH.js, debes usar diferentes cadenas para detectar los metadatos ID3 de las transmisiones en vivo o de VOD:

  • Transmisiones en vivo: 'https://developer.apple.com/streaming/emsg-id3'
  • Transmisiones de VOD: 'urn:google:dai:2018'

Pasa los metadatos de ID3 al SDK con StreamManager.processMetadata().

Para mostrar automáticamente los controles de video después de que todo se cargue y esté listo, escucha el evento MANIFEST_LOADED de DASH.js.

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 con transmisiones en vivo (formato de transmisiones DASH)

Si usas Shaka Player para la reproducción de transmisiones en vivo, usa la cadena 'emsg' para detectar eventos de metadatos. Luego, usa los datos del mensaje del evento en tu llamada a 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 con transmisiones de VOD (formato de transmisiones DASH)

Si usas Shaka Player para la reproducción de transmisiones de VOD, usa la cadena 'timelineregionenter' para escuchar los eventos de metadatos. Luego, usa los datos del mensaje del evento en tu llamada a StreamManager.processMetadata() con la cadena '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);
       }
}

Cómo controlar eventos del reproductor

Agrega objetos de escucha de eventos a los eventos pause y start del elemento de video para permitir que el usuario reanude la reproducción cuando el SDK la pausa durante las pausas publicitarias.

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

Limpia los recursos de la DAI de IMA

Cuando hayas terminado de solicitar y mostrar anuncios en una transmisión de Pod Serving con el SDK de IMA DAI, te sugerimos que limpies los recursos después de que finalice la sesión de Pod Serving. Llama a StreamManager.destroy() para detener la reproducción de la transmisión, detener todo el seguimiento de anuncios y liberar todos los recursos de transmisión cargados.

Para obtener información sobre las funciones más avanzadas del SDK, consulta las otras guías o los ejemplos en GitHub.