Gestire i metadati a tempo negli stream DAI lineari

L'SDK IMA (Interactive Media Ads) per l'inserimento di annunci dinamici (DAI) si basa sulle informazioni dei metadati incorporate nei segmenti multimediali dello stream (metadati in-band) o nel file manifest di streaming (metadati in-manifest) per tenere traccia delle posizioni degli spettatori e degli eventi annuncio lato client. I metadati vengono inviati in formati diversi, a seconda del tipo di stream riprodotto.

Il video player riceve i metadati temporali in batch. A seconda del player, i metadati possono essere visualizzati all'ora programmata o in batch. A ogni stringa di metadati è associato un timestamp di presentazione (PTS) che indica il momento in cui deve essere attivata.

La tua app è responsabile dell'acquisizione dei metadati e dell'inoltro all'SDK IMA DAI. L'SDK offre i seguenti metodi per trasmettere queste informazioni:

onTimedMetadata

Questo metodo inoltra all'SDK le stringhe di metadati pronte per essere elaborate. Richiede un singolo argomento:

  • metadata: un oggetto contenente una chiave di TXXX con un valore stringa associato preceduto da google_.
processMetadata

Questo metodo pianifica le stringhe di metadati da elaborare da parte dell'SDK dopo il PTS specificato. Prende i seguenti argomenti:

  • type: una stringa contenente il tipo di evento in fase di elaborazione. I valori accettati sono ID3 per HLS o urn:google:dai:2018 per DASH
  • data: un valore stringa preceduto da google_ o un array di byte che decodifica in una stringa di questo tipo.
  • timestamp: il timestamp in secondi in cui i dati devono essere elaborati.

Ogni tipo di stream supportato dall'SDK IMA DAI utilizza una forma univoca di metadati con timestamp, come descritto nelle sezioni seguenti.

Stream HLS MPEG2TS

Gli stream HLS con DAI lineare utilizzando i segmenti MPEG2TS passano i metadati temporali al video player tramite tag ID3 nella banda. Questi tag ID3 sono incorporati nei segmenti MPEG2TS e viene assegnato il nome del campo TXXX (per contenuti di testo personalizzati definiti dall'utente).

Riproduzione in Safari

Safari elabora i tag ID3 automaticamente come traccia nascosta, quindi gli eventi di cuechange si attivano al momento giusto per elaborare ogni porzione di metadati. Puoi passare tutti i metadati all'SDK IMA DAI, indipendentemente dai contenuti o dal tipo. I metadati non pertinenti vengono filtrati automaticamente.

Esempio:

videoElement.textTracks.addEventListener('addtrack', (e) => {
  const track = e.track;
  if (track.kind === 'metadata') {
    track.mode = 'hidden';
    track.addEventListener('cuechange', () => {
      for (const cue of track.activeCues) {
        const metadata = {};
        metadata[cue.value.key] = cue.value.data;
        streamManager.onTimedMetadata(metadata);
      }
    });
  }
});
...

HLS.js

HLS.js fornisce tag ID3 in batch tramite l'evento FRAG_PARSING_METADATA, come array di esempi. HLS.js non converte i dati ID3 da array di byte in stringhe e non esegue l'offset degli eventi nei PTS corrispondenti. Non è necessario decodificare i dati di esempio da array di byte a stringa o filtrare i tag ID3 irrilevanti, poiché l'SDK IMA DAI esegue automaticamente queste operazioni di decodifica e filtro.

Esempio:

hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
  if (streamManager && data) {
    data.samples.forEach((sample) => {
      streamManager.processMetadata('ID3', sample.data, sample.pts);
    });
  }
});
...

Stream HLS CMAF

Gli stream HLS con DAI lineare utilizzando il Common Media Application Framework (CMAF) passano i metadati temporali attraverso caselle eMSGv1 nella banda seguendo lo standard da ID3 a CMAF. Queste caselle eMSG sono incorporate all'inizio di ogni segmento multimediale e ogni eMSG ID3 contiene un PTS relativo all'ultima discontinuità dello stream.

A partire dalla versione 1.2.0 di HLS.js, entrambi i player suggeriti passano ID3 all'utente tramite CMAF come se fossero tag ID3. Per questo motivo, gli esempi seguenti sono uguali a quelli per gli stream HLS MPEG2TS. Tuttavia, questo potrebbe non essere il caso con tutti i player, quindi l'implementazione del supporto per i flussi HLS CMAF potrebbe richiedere un codice univoco per analizzare ID3 tramite eMSG.

Riproduzione in Safari

Safari tratta gli ID3 tramite i metadati eMSG come pseudo eventi ID3, fornendoli in batch, automaticamente e come tracce nascoste, affinché gli eventi cuechange vengano attivati al momento giusto per elaborare ogni porzione di metadati. È giusto passare tutti i metadati all'SDK IMA DAI, che siano pertinenti o meno ai tempi. Tutti i metadati non correlati all'inserimento di annunci dinamici vengono filtrati automaticamente.

Esempio:

videoElement.textTracks.addEventListener('addtrack', (e) => {
  const track = e.track;
  if (track.kind === 'metadata') {
    track.mode = 'hidden';
    track.addEventListener('cuechange', () => {
      for (const cue of track.activeCues) {
        const metadata = {};
        metadata[cue.value.key] = cue.value.data;
        streamManager.onTimedMetadata(metadata);
      }
    });
  }
});
...

HLS.js

A partire dalla versione 1.2.0, HLS.js tratta ID3 tramite i metadati eMSG come pseudo eventi ID3, fornendoli in batch, tramite l'evento FRAG_PARSING_METADATA, come un array di campioni. HLS.js non converte i dati ID3 da array di byte in stringhe e non esegue l'offset degli eventi nei PTS corrispondenti. Non è necessario decodificare i dati di esempio da array di byte a stringa, poiché l'SDK IMA DAI esegue automaticamente questa decodifica.

Esempio:

hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
  if (streamManager && data) {
    data.samples.forEach((sample) => {
      streamManager.processMetadata('ID3', sample.data, sample.pts);
    });
  }
});
...

Stream DASH

Gli streaming DASH con DAI lineare trasmettono i metadati come eventi manifest in uno stream di eventi con il valore schemeIdUri personalizzato urn:google:dai:2018. Ogni evento in questi flussi contiene un payload di testo e il PTS.

DASH.js

Dash.js fornisce gestori di eventi personalizzati denominati in base al valore schemaIdUri di ciascun flusso di eventi. Questi gestori personalizzati vengono attivati in batch, lasciando all'utente l'elaborazione del valore PTS per la corretta tempistica dell'evento. L'SDK IMA DAI può gestire questa situazione per te con il metodo streamManager, processMetadata().

Esempio:

const dash = dashjs.MediaPlayer().create();
dash.on('urn:google:dai:2018', (payload) => {
  const mediaId = payload.event.messageData;
  const pts = payload.event.calculatedPresentationTime;
  streamManager.processMetadata('urn:google:dai:2018', mediaId, pts);
});
...

Suonatore di Shaka

Shaka Player mostra gli eventi come parte dell'evento timelineregionenter. A causa di un'incompatibilità di formattazione con Shaka Player, il valore dei metadati deve essere recuperato non elaborato tramite la proprietà dei dettagli eventElement.attributes['messageData'].value.

Esempio:

player.addEventListener('timelineregionenter', function(event) {
  const detail = event.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;
    streamManager.processMetadata("urn:google:dai:2018", mediaId, pts);
  }
});
...

Pubblicazione dei pod

Per la pubblicazione dei pod, esistono diverse configurazioni per il trasferimento dei metadati a tempo in base ai seguenti criteri:

  • Tipo di stream live o VOD
  • Formato di streaming HLS o DASH
  • Il tipo di player utilizzato
  • Il tipo di backend DAI utilizzato

Formato stream HLS (stream live e VOD, player HLS.js)

Se utilizzi un player HLS.js, ascolta l'evento FRAG_PARSING_METADATA HLS.js per ottenere i metadati ID3 e passali all'SDK con StreamManager.processMetadata().

Per riprodurre automaticamente il video dopo che tutto è stato caricato e pronto, ascolta l'evento MANIFEST_PARSED HLS.js per attivare la riproduzione.

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 di stream DASH, tipo di stream Dal vivo e VOD)

Se usi un player DASH.js, devi utilizzare stringhe diverse per ascoltare i metadati ID3 dei live streaming o VOD:

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

Trasferisci i metadati ID3 all'SDK con StreamManager.processMetadata().

Per mostrare automaticamente i controlli video dopo che tutti gli elementi sono stati caricati e pronti, ascolta l'evento MANIFEST_LOADED 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 live streaming (formato di stream DASH)

Se usi il player Shaka per la riproduzione in live streaming, usa la stringa 'emsg' per ascoltare gli eventi dei metadati. Quindi, utilizza i dati dei messaggi dell'evento nella chiamata al numero 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 stream VOD (formato di stream DASH)

Se utilizzi il player Shaka per la riproduzione dello streaming VOD, utilizza la stringa 'timelineregionenter' per ascoltare gli eventi dei metadati. Quindi, utilizza i dati dei messaggi dell'evento nella chiamata a StreamManager.processMetadata() con la stringa '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);
       }
}