Os SDKs do IMA facilitam a integração de anúncios multimídia aos seus sites e apps. Os SDKs do IMA podem solicitar anúncios de qualquer servidor de anúncios compatível com VAST e gerenciar a veiculação de anúncios nos seus apps. Com os SDKs do IMA DAI, os apps fazem uma solicitação de transmissão para anúncios e vídeos de conteúdo, seja VOD ou conteúdo ao vivo. O SDK retorna uma transmissão de vídeo combinada para que você não precise alternar entre o anúncio e o vídeo de conteúdo no app.
Selecione a solução de DAI de seu interesse
Veiculação de conjunto DAI
Este guia demonstra como reproduzir uma transmissão de veiculação de conjunto DAI para conteúdo ao vivo ou VOD usando o SDK DAI do IMA para HTML5 com um player de vídeo que depende do hls.js para reprodução. Para conferir ou seguir um exemplo de integração completo, com suporte para HLS.js e reprodução do Safari, consulte o exemplo de veiculação de pods HLS. Para suporte ao DASH.js, consulte o exemplo de envio de pods DASH. É possível fazer o download desses apps de exemplo na página de lançamento do DAI HTML5 no GitHub.
Informações gerais sobre a Veiculação de conjunto DAI
A implementação do pod usando o SDK DAI do IMA envolve dois componentes principais, que são demonstrados neste guia:
PodStreamRequest
/PodVodStreamRequest
: um objeto que define uma solicitação de transmissão para os servidores de publicidade do Google. As solicitações especificam um código de rede, e oPodStreamRequest
também exige uma chave de recurso personalizada e uma chave de API opcional. Ambos incluem outros parâmetros opcionais.StreamManager
: um objeto que processa a comunicação entre o stream de vídeo e o SDK do IMA DAI, como acionar pings de rastreamento e encaminhar eventos de stream para o editor.
Pré-requisitos
Antes de começar, os seguintes itens são necessários:
Três arquivos vazios:
- dai.html
- dai.css
- dai.js
Python instalado no computador ou um servidor da Web ou outro ambiente de desenvolvimento hospedado para uso em testes
Configurar um ambiente de desenvolvimento
Como o SDK carrega dependências usando o mesmo protocolo da página de onde ele é carregado, é necessário usar um servidor da Web para testar o app. Uma maneira rápida de iniciar um servidor de desenvolvimento local é usar o servidor integrado do Python.
Usando uma linha de comando, no diretório que contém o arquivo
index.html
, execute:python -m http.server 8000
Em um navegador da Web, acesse
http://localhost:8000/
.Você também pode usar qualquer outro ambiente de desenvolvimento hospedado ou servidor da Web, como o Apache HTTP Server.
Criar um player de vídeo
Primeiro, modifique dai.html para criar um elemento de vídeo HTML5 e um div para
usar nos elementos da interface do anúncio. Adicione também as tags necessárias para carregar os arquivos dai.css
e dai.js, além de importar o player de vídeo hls.js
.
Em seguida, modifique dai.css para especificar o tamanho e a posição dos elementos da página.
Por fim, em dai.js, defina variáveis para armazenar as informações da solicitação de stream
e uma função initPlayer()
para ser executada quando a página for carregada.
As constantes de solicitação de stream são as seguintes:
BACKUP_STREAM
: um URL para um stream de backup a ser reproduzido caso o processamento de anúncios encontre um erro fatal.STREAM_URL
: usado apenas para transmissões ao vivo. O URL do stream de vídeo fornecido pelo manipulador de manifesto ou parceiro terceirizado que usa a veiculação de conjunto. Ele precisa exigir que você insira o ID do stream fornecido pelo SDK do IMA DAI antes de fazer uma solicitação. Nesse caso, o URL do fluxo inclui um marcador de posição,[[STREAMID]]
, que é substituído pelo ID do fluxo antes de fazer uma solicitação.NETWORK_CODE
: é o código de rede da sua conta do Ad Manager 360.CUSTOM_ASSET_KEY
: usado apenas para transmissões ao vivo. A chave de recurso personalizada que identifica seu evento de veiculação de pod no Ad Manager 360. Ele pode ser criado pelo manipulador de manifesto ou pelo parceiro de veiculação de pods de terceiros.API_KEY
: usado apenas para transmissões ao vivo. Uma chave de API opcional que pode ser necessária para recuperar um ID de stream do SDK do 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="ad-ui"></div>
</body>
</html>
dai.css
#video,
#ad-ui {
width: 640px;
height: 360px;
position: absolute;
top: 35px;
left: 0;
}
#ad-ui {
cursor: pointer;
}
dai.js
var BACKUP_STREAM =
'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'
// Stream Config.
const STREAM_URL = "https://encodersim.sandbox.google.com/masterPlaylist/...&stream_id=[[STREAMID]]";
const NETWORK_CODE = "51636543";
const CUSTOM_ASSET_KEY = "google-sample";
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');
}
Carregar o SDK do IMA DAI
Em seguida, adicione o framework DAI usando uma tag de script em dai.html, antes da tag 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>
...
Inicializar o StreamManager e fazer uma solicitação de transmissão ao vivo ou VOD
Disponibilização de pods de transmissão ao vivo
Para solicitar um conjunto de anúncios, crie um ima.dai.api.StreamManager
, que
é responsável por solicitar e gerenciar fluxos de DAI. O construtor recebe
um elemento de vídeo, e a instância resultante recebe um elemento de interface do anúncio para processar as interações
com o anúncio.
Em seguida, defina uma função para solicitar a transmissão ao vivo do pod. Essa função
primeiro cria um PodStreamRequest
, o configura com os parâmetros de streamRequest
fornecidos na etapa 2 e, em seguida, chama streamManager.requestStream()
com esse objeto de solicitação.
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);
}
Veiculação de conjunto VOD
Para solicitar um conjunto de anúncios, crie um ima.dai.api.StreamManager
, que
é responsável por solicitar e gerenciar fluxos de DAI. O construtor recebe
um elemento de vídeo, e a instância resultante recebe um elemento de interface do anúncio para processar as interações
com o anúncio.
Em seguida, defina uma função para solicitar o stream de VOD de serviço de pod. Essa função
primeiro cria um PodVodStreamRequest
, o configura com os parâmetros de streamRequest
fornecidos na etapa 2 e, em seguida, chama streamManager.requestStream()
com esse objeto de solicitação.
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);
}
Processar eventos de transmissão
Disponibilização de pods de transmissão ao vivo
Em seguida, implemente listeners de eventos para os principais eventos de vídeo. Este exemplo processa
os eventos STREAM_INITIALIZED
, ERROR
, AD_BREAK_STARTED
e AD_BREAK_ENDED
chamando uma função onStreamEvent()
. Essa função processa o carregamento
e os erros do stream, além de desativar os controles do player enquanto um anúncio
está sendo veiculado, o que é necessário para o SDK. Quando o stream é carregado, o player
de vídeo carrega e reproduz o URL fornecido usando uma função 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);
}
Veiculação de conjunto VOD
Em seguida, implemente listeners de eventos para os principais eventos de vídeo. Este exemplo processa
os eventos STREAM_INITIALIZED
, LOADED
, ERROR
, AD_BREAK_STARTED
e
AD_BREAK_ENDED
chamando uma função onStreamEvent()
. Essa
função lida com o carregamento e os erros do stream, além de desativar os controles
do player enquanto um anúncio é reproduzido, o que é necessário pelo SDK.
Além disso, as transmissões de fornecimento de pods de VOD exigem a chamada
StreamManager.loadStreamMetadata()
em resposta ao evento
STREAM_INITIALIZED
. Você também precisa solicitar um URL de transmissão ao vivo do seu
parceiro de tecnologia de vídeo (VTP, na sigla em inglês). Quando a chamada loadStreamMetadata()
é bem-sucedida,
ela aciona um evento LOADED
, em que você precisa chamar uma função loadStream()
com o URL do stream para carregar e reproduzir o stream.
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);
}
Processar metadados de transmissão
Nesta etapa, você implementa listeners de evento para metadados para notificar o SDK quando eventos de anúncios ocorrem. A detecção de eventos de metadados no stream pode variar, dependendo do formato (HLS ou DASH), do tipo de transmissão (ao vivo ou VOD), do tipo de player e do tipo de back-end da DAI usado. Consulte nosso guia de metadados cronometrados para mais informações.
Formato de transmissão HLS (transmissões ao vivo e VOD, player HLS.js)
Se você estiver usando um player HLS.js, detecte
o evento FRAG_PARSING_METADATA
do HLS.js para receber os metadados do ID3 e transmiti-los ao
SDK com StreamManager.processMetadata()
.
Para reproduzir o vídeo automaticamente depois que tudo estiver carregado e pronto, ouça
o evento MANIFEST_PARSED
do HLS.js para acionar a reprodução.
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 transmissões DASH, tipo de transmissão ao vivo e VOD)
Se você estiver usando um player DASH.js, use strings diferentes para detectar metadados ID3 para transmissões ao vivo ou VOD:
- Transmissões ao vivo:
'https://developer.apple.com/streaming/emsg-id3'
- Transmissões de VOD:
'urn:google:dai:2018'
Transmita os metadados ID3 para o SDK com StreamManager.processMetadata()
.
Para mostrar automaticamente os controles de vídeo depois que tudo estiver carregado e pronto,
ouça o evento MANIFEST_LOADED
do 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 com transmissões ao vivo (formato de transmissões DASH)
Se você estiver usando o player Shaka para
reprodução de transmissão ao vivo, use a string 'emsg'
para detectar eventos de metadados.
Em seguida, use os dados da mensagem de evento na chamada para 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 com transmissões VOD (formato de transmissões DASH)
Se você estiver usando o player Shaka para
reprodução de fluxo de VOD, use a string 'timelineregionenter'
para detectar
eventos de metadados. Em seguida, use os dados da mensagem de evento na chamada para
StreamManager.processMetadata()
com a string '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);
}
}
Processar eventos do player
Adicione listeners de eventos aos eventos pause
e start
do elemento de vídeo para permitir
que o usuário retome a reprodução quando o SDK for pausado durante intervalos de anúncios.
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';
}
}
Limpar recursos da DAI do IMA
Quando você terminar de solicitar e exibir anúncios em um fluxo de veiculação de pods
com o SDK DAI do IMA, sugerimos que limpe todos os recursos depois que a
sessão de veiculação de pods for concluída. Chame StreamManager.destroy()
para interromper a reprodução
do stream, parar todo o rastreamento de anúncios e liberar todos os recursos de stream carregados.
Para saber mais sobre recursos avançados do SDK, consulte os outros guias ou os exemplos no GitHub.