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 de VOD con el SDK de IMA para DAI para HTML5 con un reproductor de video que se basa en hls.js para la reproducción. Para ver o seguir una integración de ejemplo completa, con compatibilidad con HLS.js y la reproducción de Safari, consulta el ejemplo de publicación de grupos de anuncios de HLS. Para obtener información sobre la compatibilidad con DASH.js, consulta el ejemplo de publicación de grupos de anuncios de DASH. Puedes descargar estas apps de ejemplo desde la página de versiones de DAI en HTML5 de GitHub.
Descripción general de la Publicación de grupos de anuncios de DAI
La implementación de la publicación de grupos de anuncios con el SDK de IMA para DAI implica dos componentes principales, que se muestran 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 elPodStreamRequesttambié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 IMA para DAI, como activar pings de seguimiento y reenviar 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 realizar 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.
Con una línea de comandos, desde el directorio que contiene tu archivo
index.html, ejecuta lo siguiente:python -m http.server 8000En un navegador web, ve a
http://localhost:8000/.También puedes usar cualquier otro entorno de desarrollo alojado o servidor web, como el servidor HTTP Apache.
Crea un reproductor de video
Primero, modifica dai.html para crear un elemento de video HTML5 y un div que se usará para 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 de 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 almacenar la información de la solicitud de transmisión y una función initPlayer() que se ejecute cuando se cargue la página.
Las constantes de solicitud de transmisión son las siguientes:
BACKUP_STREAM: Es una URL para una transmisión de copia de seguridad que se reproducirá en caso de que el proceso de anuncios encuentre un error fatal.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 requerir que insertes el ID de transmisión que proporciona el SDK de IMA para DAI antes de realizar 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 grupos de anuncios en Ad Manager 360. Tu manipulador de manifiestos o socio externo de publicación de grupos de anuncios puede crear este ID.API_KEY: Solo se usa para transmisiones en vivo. Es una clave de API opcional que se puede requerir para recuperar un ID de transmisión del SDK de IMA para 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 para DAI
Luego, agrega el framework de DAI con una etiqueta de secuencia de comandos en dai.html, antes de la etiqueta para 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 el StreamManager y realiza una solicitud de transmisión en vivo o de VOD
Publicación de anuncios en grupos de anuncios de transmisiones en vivo
Para solicitar un conjunto de anuncios, crea un objeto ima.dai.api.StreamManager, que se encarga de solicitar y administrar las 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 se encarga de solicitar y administrar las 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 el flujo 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 anuncios en grupos de anuncios 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, y también inhabilita 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, y también inhabilita los controles del reproductor mientras se reproduce un anuncio, lo que requiere el SDK.
Además, las transmisiones de la Publicación de grupos de anuncios de VOD 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);
}
Controla los metadatos de la transmisión
En este paso, implementarás objetos de escucha de eventos para los metadatos con el objetivo de notificar al SDK cuando se produzcan eventos de anuncios. La escucha de eventos de metadatos en la transmisión puede variar según el formato de la transmisión (HLS o DASH), el tipo de transmisión (en vivo o VOD), el tipo de reproductor y el tipo de backend de DAI que se use. Consulta nuestra guía de metadatos cronometrados para obtener más información.
Formato de transmisión HLS (transmisiones en vivo y de VOD, reproductor HLS.js)
Si usas un reproductor HLS.js, escucha el evento FRAG_PARSING_METADATA de HLS.js para obtener metadatos de ID3 y pásalos al SDK con StreamManager.processMetadata().
Para reproducir automáticamente el video después de que todo esté cargado y 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 de VOD)
Si usas un reproductor DASH.js, debes usar diferentes cadenas para escuchar los metadatos de 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 ID3 al SDK con StreamManager.processMetadata().
Para mostrar automáticamente los controles de video después de que todo esté cargado y 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 el reproductor Shaka para reproducir transmisiones en vivo, usa la cadena 'emsg' para escuchar 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
reproducir transmisiones de VOD, usa la cadena 'timelineregionenter' para escuchar
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 los 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 se detenga 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';
}
}
Cómo limpiar los recursos de IMA para DAI
Cuando hayas terminado de solicitar y mostrar anuncios en un flujo de publicación de grupos de anuncios con el SDK de IMA para DAI, te sugerimos que limpies los recursos después de que se complete la sesión de publicación de grupos de anuncios. 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 más información sobre las funciones más avanzadas del SDK, consulta las otras guías o los ejemplos en GitHub.