Configurer le SDK IMA pour l'insertion dynamique d'annonces

Les SDK IMA permettent d'intégrer facilement des annonces multimédias à vos sites Web et applications. Les SDK IMA peuvent demander des annonces à n'importe quel ad server conforme à la norme VAST et gérer la lecture des annonces dans vos applications. Avec les SDK IMA DAI, les applications envoient une demande de flux pour les annonces et le contenu vidéo (VOD ou contenu en direct). Le SDK renvoie ensuite un flux vidéo combiné, ce qui vous évite d'avoir à gérer le basculement entre les vidéos d'annonces et de contenu dans votre application.

Sélectionnez la solution DAI qui vous intéresse.

Insertion dynamique de séries d'annonces

Ce guide explique comment lire un flux d'insertion dynamique de séries d'annonces pour du contenu en direct ou à la demande, à l'aide du SDK IMA DAI pour HTML5 avec un lecteur vidéo qui s'appuie sur hls.js pour la lecture. Pour afficher ou suivre un exemple d'intégration complet, compatible avec HLS.js et la lecture Safari, consultez l'exemple de diffusion de pods HLS. Pour en savoir plus sur la compatibilité avec DASH.js, consultez l'exemple de diffusion de pods DASH. Vous pouvez télécharger ces exemples d'applications sur la page de version GitHub pour HTML5 DAI.

Présentation de l'insertion dynamique de séries d'annonces

L'implémentation de la diffusion de séries d'annonces à l'aide du SDK IMA DAI implique deux composants principaux, qui sont présentés dans ce guide :

  • PodStreamRequest/PodVodStreamRequest : objet qui définit une demande de flux aux serveurs publicitaires de Google. Les requêtes spécifient un code de réseau, et PodStreamRequest nécessite également une clé d'élément personnalisé et une clé API facultative. Les deux incluent d'autres paramètres facultatifs.

  • StreamManager : objet qui gère la communication entre le flux vidéo et le SDK IMA DAI, par exemple en déclenchant des pings de suivi et en transmettant les événements de flux à l'éditeur.

Prérequis

Avant de commencer, vous avez besoin des éléments suivants :

  • Trois fichiers vides :

    • dai.html
    • dai.css
    • dai.js
  • Python installé sur votre ordinateur, ou un serveur Web ou un autre environnement de développement hébergé à utiliser pour les tests

Configurer un environnement de développement

Étant donné que le SDK charge les dépendances à l'aide du même protocole que la page à partir de laquelle il est chargé, vous devez utiliser un serveur Web pour tester votre application. Un moyen rapide de démarrer un serveur de développement local consiste à utiliser le serveur intégré de Python.

  1. À l'aide d'une ligne de commande, exécutez la commande suivante à partir du répertoire contenant votre fichier index.html :

    python -m http.server 8000
  2. Dans un navigateur Web, accédez à http://localhost:8000/.

    Vous pouvez également utiliser n'importe quel autre environnement de développement ou serveur Web hébergé, tel que le serveur HTTP Apache.

Créer un lecteur vidéo

Commencez par modifier dai.html pour créer un élément vidéo HTML5 et un div à utiliser pour les éléments d'UI d'annonce. Ajoutez également les tags nécessaires pour charger les fichiers dai.css et dai.js, ainsi que pour importer le lecteur vidéo hls.js.

Modifiez ensuite dai.css pour spécifier la taille et la position des éléments de la page. Enfin, dans dai.js, définissez des variables pour contenir les informations de la demande de flux et une fonction initPlayer() à exécuter au chargement de la page.

Les constantes de demande de flux sont les suivantes :

  • BACKUP_STREAM : URL d'un flux de sauvegarde à lire si le processus d'annonces rencontre une erreur fatale.

  • STREAM_URL : utilisé uniquement pour les diffusions en direct. URL du flux vidéo fournie par votre outil de manipulation du fichier manifeste ou votre partenaire tiers utilisant la diffusion de séries d'annonces. Il devrait vous demander d'insérer l'ID de flux fourni par le SDK IMA DAI avant d'envoyer une demande. Dans ce cas, l'URL du flux inclut un espace réservé, [[STREAMID]], qui est remplacé par l'ID du flux avant d'envoyer une requête.

  • NETWORK_CODE : code de réseau de votre compte Ad Manager 360.

  • CUSTOM_ASSET_KEY : utilisé uniquement pour les diffusions en direct. Clé d'élément personnalisé qui identifie votre événement de diffusion de pod dans Ad Manager 360. Il peut être créé par votre outil de manipulation du fichier manifeste ou par un partenaire tiers d'insertion de séries d'annonces.

  • API_KEY : utilisé uniquement pour les diffusions en direct. Clé API facultative qui peut être requise pour récupérer un ID de flux à partir du SDK 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');
}

Charger le SDK IMA DAI

Ensuite, ajoutez le framework DAI à l'aide d'une balise de script dans dai.html, avant la balise pour 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>
...

Initialiser le StreamManager et envoyer une demande de flux en direct ou de VOD

Diffusion de pods de diffusions en direct

Pour demander un ensemble d'annonces, créez un ima.dai.api.StreamManager, qui est responsable de la demande et de la gestion des flux d'insertion dynamique d'annonces. Le constructeur prend un élément vidéo et l'instance résultante prend un élément d'UI d'annonce pour gérer les interactions avec l'annonce.

Définissez ensuite une fonction pour demander la diffusion en direct du pod. Cette fonction crée d'abord un PodStreamRequest, le configure avec les paramètres streamRequest fournis à l'étape 2, puis appelle streamManager.requestStream() avec cet objet de requête.

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

Diffusion de séries d'annonces VOD

Pour demander un ensemble d'annonces, créez un ima.dai.api.StreamManager, qui est responsable de la demande et de la gestion des flux d'insertion dynamique d'annonces. Le constructeur prend un élément vidéo et l'instance résultante prend un élément d'UI d'annonce pour gérer les interactions avec l'annonce.

Définissez ensuite une fonction pour demander le flux VOD de diffusion de pod. Cette fonction crée d'abord un PodVodStreamRequest, le configure avec les paramètres streamRequest fournis à l'étape 2, puis appelle streamManager.requestStream() avec cet objet de requête.

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

Gérer les événements de flux

Diffusion de pods de diffusions en direct

Ensuite, implémentez des écouteurs d'événements pour les événements vidéo majeurs. Cet exemple gère les événements STREAM_INITIALIZED, ERROR, AD_BREAK_STARTED et AD_BREAK_ENDED en appelant une fonction onStreamEvent(). Cette fonction gère le chargement et les erreurs du flux, ainsi que la désactivation des commandes du lecteur pendant la lecture d'une annonce, ce qui est requis par le SDK. Lorsque le flux est chargé, le lecteur vidéo charge et lit l'URL fournie à l'aide d'une fonction 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);
}

Diffusion de séries d'annonces VOD

Ensuite, implémentez des écouteurs d'événements pour les événements vidéo majeurs. Cet exemple gère les événements STREAM_INITIALIZED, LOADED, ERROR, AD_BREAK_STARTED et AD_BREAK_ENDED en appelant une fonction onStreamEvent(). Cette fonction gère le chargement et les erreurs du flux, ainsi que la désactivation des commandes du lecteur pendant la lecture d'une annonce, ce qui est requis par le SDK.

De plus, les flux de diffusion de pods VOD nécessitent l'appel de StreamManager.loadStreamMetadata() en réponse à l'événement STREAM_INITIALIZED. Vous devez également demander une URL de flux à votre partenaire technologique vidéo (PTV). Une fois l'appel loadStreamMetadata() réussi, il déclenche un événement LOADED, où vous devez appeler une fonction loadStream() avec l'URL de votre flux pour charger et lire le flux.

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

Gérer les métadonnées du flux

Dans cette étape, vous allez implémenter des écouteurs d'événements pour les métadonnées afin d'informer le SDK lorsque des événements publicitaires se produisent. L'écoute des événements de métadonnées dans le flux peut varier en fonction du format du flux (HLS ou DASH), du type de flux (flux en direct ou VOD), du type de lecteur et du type de backend DAI utilisé. Pour en savoir plus, consultez notre guide sur les métadonnées temporelles.

Format de flux HLS (flux en direct et VOD, lecteur HLS.js)

Si vous utilisez un lecteur HLS.js, écoutez l'événement FRAG_PARSING_METADATA HLS.js pour obtenir les métadonnées ID3 et les transmettre au SDK avec StreamManager.processMetadata().

Pour lire automatiquement la vidéo une fois que tout est chargé et prêt, écoutez l'événement MANIFEST_PARSED HLS.js pour déclencher la lecture.

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 (format de flux DASH, type de flux en direct et VOD)

Si vous utilisez un lecteur DASH.js, vous devez utiliser des chaînes différentes pour écouter les métadonnées ID3 des flux en direct ou VOD :

  • Diffusions en direct : 'https://developer.apple.com/streaming/emsg-id3'
  • Flux VOD : 'urn:google:dai:2018'

Transmettez les métadonnées ID3 au SDK avec StreamManager.processMetadata().

Pour afficher automatiquement les commandes vidéo une fois que tout est chargé et prêt, écoutez l'événement 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 avec des diffusions en direct (format de flux DASH)

Si vous utilisez Shaka Player pour la lecture de flux en direct, utilisez la chaîne 'emsg' pour écouter les événements de métadonnées. Ensuite, utilisez les données du message d'événement dans votre appel à 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 avec des flux VOD (format de flux DASH)

Si vous utilisez Shaka Player pour la lecture de flux VOD, utilisez la chaîne 'timelineregionenter' pour écouter les événements de métadonnées. Utilisez ensuite les données du message d'événement dans votre appel à StreamManager.processMetadata() avec la chaîne '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);
       }
}

Gérer les événements du lecteur

Ajoutez des écouteurs d'événements aux événements pause et start de l'élément vidéo pour permettre à l'utilisateur de reprendre la lecture lorsque le SDK la met en pause pendant les pauses publicitaires.

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

Nettoyer les composants IMA DAI

Lorsque vous avez terminé de demander et d'afficher des annonces dans un flux Pod Serving avec le SDK IMA DAI, nous vous suggérons de nettoyer toutes les ressources une fois la session Pod Serving terminée. Appelez StreamManager.destroy() pour arrêter la lecture du flux, arrêter tout suivi des annonces et libérer tous les éléments de flux chargés.

Pour en savoir plus sur les fonctionnalités avancées du SDK, consultez les autres guides ou les exemples sur GitHub.