Einführung in das IMA DAI SDK

Mit IMA SDKs lassen sich Multimedia-Anzeigen ganz einfach in Websites und Apps einbinden. Mit IMA SDKs können Anzeigen von jedem VAST-kompatiblen Ad-Server angefordert und die Anzeigenwiedergabe in Ihren Apps verwaltet werden. Mit IMA DAI SDKs senden Apps eine Streamanfrage für Anzeigen- und Videoinhalte – entweder VOD- oder Liveinhalte. Das SDK gibt dann einen kombinierten Videostream zurück, sodass Sie nicht zwischen Anzeigen- und Inhaltsvideo in Ihrer App wechseln müssen.

Wählen Sie die gewünschte dynamische Anzeigenbereitstellungslösung aus.

Pod-Auslieferung mit dynamischer Anzeigenbereitstellung

In dieser Anleitung wird gezeigt, wie du einen Stream mit dynamischer Anzeigenbereitstellung und Pod-Auslieferung für Live- oder VOD-Inhalte mit dem IMA DAI SDK für HTML5 und einem Videoplayer abspielst, der für die Wiedergabe auf hls.js angewiesen ist. Eine fertige Beispielintegration mit Unterstützung für HLS.js und Safari-Wiedergabe findest du im Beispiel für das HLS-Pod-Bereitstellen. Informationen zur Unterstützung von DASH.js findest du im Beispiel für das DASH-Pod-Bereitstellen. Sie können diese Beispiel-Apps von der GitHub-Releaseseite für HTML5-DAUs herunterladen.

Pod-Auslieferung mit dynamischer Anzeigenbereitstellung – Übersicht

Die Implementierung der Pod-Auslieferung mit dem IMA DAI SDK umfasst zwei Hauptkomponenten, die in diesem Leitfaden veranschaulicht werden:

  • PodStreamRequest / PodVodStreamRequest: Ein Objekt, das eine Streamanfrage an die Werbeserver von Google definiert. Anfragen müssen einen Netzwerkcode angeben. Für die PodStreamRequest ist außerdem ein benutzerdefinierter Asset-Schlüssel und optional ein API-Schlüssel erforderlich. Beide enthalten weitere optionale Parameter.

  • StreamManager: Ein Objekt, das die Kommunikation zwischen dem Videostream und dem IMA DAI SDK verwaltet, z. B. das Auslösen von Tracking-Pings und das Weiterleiten von Stream-Ereignissen an den Publisher.

Vorbereitung

Für den Start ist Folgendes erforderlich:

  • Drei leere Dateien:

    • dai.html
    • dai.css
    • dai.js
  • Python auf Ihrem Computer oder ein Webserver oder eine andere gehostete Entwicklungsumgebung zum Testen

Entwicklungsumgebung konfigurieren

Da das SDK Abhängigkeiten mit demselben Protokoll wie die Seite lädt, von der es geladen wird, müssen Sie einen Webserver verwenden, um Ihre App zu testen. Eine schnelle Möglichkeit, einen lokalen Entwicklungsserver zu starten, ist der integrierte Server von Python.

  1. Führen Sie in einer Befehlszeile im Verzeichnis, in dem sich die Datei index.html befindet, Folgendes aus:

    python -m http.server 8000
  2. Rufen Sie in einem Webbrowser http://localhost:8000/ auf.

    Sie können auch jede andere gehostete Entwicklungsumgebung oder jeden anderen Webserver verwenden, z. B. den Apache HTTP Server.

Videoplayer erstellen

Ändern Sie zuerst dai.html, um ein HTML5-Videoelement und ein Div-Element für die Anzeigen-UI zu erstellen. Füge außerdem die erforderlichen Tags hinzu, um die Dateien dai.css und dai.js zu laden und den hls.js-Videoplayer zu importieren.

Ändern Sie dann dai.css, um die Größe und Position der Seitenelemente anzugeben. Definiere abschließend in dai.js Variablen für die Informationen zur Streamanfrage und eine initPlayer()-Funktion, die beim Laden der Seite ausgeführt wird.

Die Konstanten für Streamanfragen sind:

  • BACKUP_STREAM: Eine URL für einen Sicherungsstream, der wiedergegeben wird, falls beim Anzeigenprozess ein schwerwiegender Fehler auftritt.

  • STREAM_URL: Wird nur für Livestreams verwendet. Die Videostream-URL, die von deinem Manifest-Bearbeiter oder Drittanbieterpartner mit Pod-Auslieferung bereitgestellt wird. Du solltest die vom IMA DAI SDK bereitgestellte Stream-ID eingeben müssen, bevor du eine Anfrage sendest. In diesem Fall enthält die Stream-URL einen Platzhalter, [[STREAMID]], der vor dem Senden einer Anfrage durch die Stream-ID ersetzt wird.

  • NETWORK_CODE: Der Netzwerkcode für Ihr Ad Manager 360-Konto.

  • CUSTOM_ASSET_KEY: Wird nur für Livestreams verwendet. Der benutzerdefinierte Asset-Schlüssel, mit dem das Pod-Auslieferungsereignis in Ad Manager 360 identifiziert wird. Diese kann von deinem Manifest-Bearbeiter oder Pod-Auslieferungspartner erstellt werden.

  • API_KEY: Wird nur für Livestreams verwendet. Optionaler API-Schlüssel, der zum Abrufen einer Stream-ID aus dem IMA DAI SDK erforderlich sein kann.

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

IMA DAI SDK laden

Fügen Sie als Nächstes das DAI-Framework mit einem Script-Tag in dai.html vor dem Tag für dai.js ein.

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 initialisieren und eine Live- oder VOD-Streamanfrage stellen

Bereitstellung von Livestream-Pods

Wenn du eine Reihe von Anzeigen anfordern möchtest, musst du eine ima.dai.api.StreamManager erstellen. Diese ist für das Anfordern und Verwalten von dynamischen Anzeigenstreams verantwortlich. Der Konstruktor nimmt ein Videoelement und die resultierende Instanz ein Anzeigen-UI-Element zur Verarbeitung von Anzeigeninteraktionen an.

Definiere dann eine Funktion, um den Livestream für die Pod-Bereitstellung anzufordern. Diese Funktion erstellt zuerst eine PodStreamRequest, konfiguriert sie mit den in Schritt 2 angegebenen streamRequest-Parametern und ruft dann streamManager.requestStream() mit diesem Anfrageobjekt auf.

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-Auslieferung

Wenn du eine Reihe von Anzeigen anfordern möchtest, musst du eine ima.dai.api.StreamManager erstellen. Diese ist für das Anfordern und Verwalten von dynamischen Anzeigenstreams verantwortlich. Der Konstruktor nimmt ein Videoelement und die resultierende Instanz ein Anzeigen-UI-Element zur Verarbeitung von Anzeigeninteraktionen an.

Definiere dann eine Funktion, um den VOD-Stream für die Pod-Bereitstellung anzufordern. Diese Funktion erstellt zuerst eine PodVodStreamRequest, konfiguriert sie mit den in Schritt 2 angegebenen streamRequest-Parametern und ruft dann streamManager.requestStream() mit diesem Anfrageobjekt auf.

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

Stream-Ereignisse verarbeiten

Bereitstellung von Livestream-Pods

Implementiere als Nächstes Ereignis-Listener für wichtige Videoereignisse. In diesem Beispiel werden die Ereignisse STREAM_INITIALIZED, ERROR, AD_BREAK_STARTED und AD_BREAK_ENDED durch Aufrufen einer onStreamEvent()-Funktion verarbeitet. Diese Funktion kümmert sich um das Stream-Laden und Fehler sowie um die Deaktivierung der Playersteuerung während der Wiedergabe einer Anzeige, was vom SDK gefordert wird. Wenn der Stream geladen wird, lädt der Videoplayer die angegebene URL mit einer loadStream()-Funktion und spielt sie ab.

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-Auslieferung

Implementiere als Nächstes Ereignis-Listener für wichtige Videoereignisse. In diesem Beispiel werden die Ereignisse STREAM_INITIALIZED, LOADED, ERROR, AD_BREAK_STARTED und AD_BREAK_ENDED durch Aufrufen einer onStreamEvent()-Funktion verarbeitet. Diese Funktion verarbeitet das Stream-Laden und Fehler und deaktiviert die Playersteuerung, während eine Anzeige wiedergegeben wird. Dies ist vom SDK erforderlich.

Bei VOD-Pod-Streaming-Streams muss außerdem StreamManager.loadStreamMetadata() als Reaktion auf das Ereignis STREAM_INITIALIZED aufgerufen werden. Außerdem musst du eine Stream-URL von deinem Videotechnologiepartner (VTP) anfordern. Nach einem erfolgreichen loadStreamMetadata()-Aufruf wird das Ereignis LOADED ausgelöst. Hier solltest du eine loadStream()-Funktion mit deiner Stream-URL aufrufen, um den Stream zu laden und abzuspielen.

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

Streammetadaten verarbeiten

In diesem Schritt implementieren Sie Ereignis-Listener für Metadaten, um das SDK zu benachrichtigen, wenn Anzeigenereignisse auftreten. Das Abhören von In-Stream-Metadatenereignissen kann je nach Streamformat (HLS oder DASH), Streamtyp (Live- oder VOD-Stream), Playertyp und verwendetem DAI-Backend variieren. Weitere Informationen findest du in unserem Leitfaden zu zeitbasierten Metadaten.

HLS-Streamformat (Live- und VOD-Streams, HLS.js-Player)

Wenn du einen HLS.js-Player verwendest, warte auf das HLS.js-Ereignis FRAG_PARSING_METADATA, um ID3-Metadaten zu erhalten und sie mit StreamManager.processMetadata() an das SDK weiterzuleiten.

Wenn das Video automatisch abgespielt werden soll, nachdem alle Inhalte geladen und bereit sind, warte auf das HLS.js-Ereignis MANIFEST_PARSED, um die Wiedergabe auszulösen.

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-Streams-Format, Livestream- und VOD-Streamtyp)

Wenn du einen DASH.js-Player verwendest, musst du unterschiedliche Strings verwenden, um nach ID3-Metadaten für Live- oder VOD-Streams zu suchen:

  • Livestreams: 'https://developer.apple.com/streaming/emsg-id3'
  • VOD-Streams: 'urn:google:dai:2018'

Übergebe die ID3-Metadaten mit StreamManager.processMetadata() an das SDK.

Wenn die Videosteuerung automatisch angezeigt werden soll, nachdem alles geladen und bereit ist, musst du das DASH.js-Ereignis MANIFEST_LOADED überwachen.

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 mit Livestreams (DASH-Streams)

Wenn du für die Livestreamwiedergabe den Shaka-Player verwendest, verwende den String 'emsg', um auf Metadatenereignisse zu warten. Verwende dann die Daten der Ereignisnachricht in deinem Aufruf von 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 mit VOD-Streams (DASH-Streams-Format)

Wenn du den Shaka-Player für die Wiedergabe von VOD-Streams verwendest, verwende den String 'timelineregionenter', um auf Metadatenereignisse zu warten. Verwenden Sie dann die Daten der Ereignisnachricht in Ihrem Aufruf an StreamManager.processMetadata() mit dem 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);
       }
}

Spielerereignisse verarbeiten

Füge den Ereignissen pause und start des Videoelements Ereignis-Listener hinzu, damit der Nutzer die Wiedergabe fortsetzen kann, wenn das SDK während Werbeunterbrechungen pausiert.

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-Assets bereinigen

Wenn du Anzeigen in einem Pod-Auslieferungsstream mit dem IMA DAI SDK angefordert und ausgeliefert hast, solltest du nach Abschluss der Pod-Auslieferungssitzung alle Ressourcen bereinigen. Rufe StreamManager.destroy() auf, um die Streamwiedergabe zu beenden, alle Anzeigen zu erfassen und alle geladenen Stream-Assets freizugeben.

Weitere Informationen zu erweiterten SDK-Funktionen finden Sie in den anderen Anleitungen oder in den Beispielen auf GitHub.