Le SDK IMA (Interactive Media Ads) pour l'insertion dynamique d'annonces (DAI) s'appuie sur des informations de métadonnées intégrées aux segments média du flux (métadonnées dans le flux) ou au fichier manifeste du flux (métadonnées dans le manifeste) pour suivre les positions des spectateurs et les événements publicitaires côté client. Les métadonnées sont envoyées dans différents formats, selon le type de flux lu.
Le lecteur vidéo reçoit les métadonnées temporelles par lots. Selon le lecteur, les métadonnées peuvent être affichées à l'heure prévue ou par lots. Chaque chaîne de métadonnées est associée à un code temporel de présentation (PTS) indiquant le moment où elle doit être déclenchée.
Votre application est chargée de capturer les métadonnées et de les transférer au SDK IMA DAI. Le SDK propose les méthodes suivantes pour transmettre ces informations :
- onTimedMetadata
Cette méthode transmet au SDK les chaînes de métadonnées prêtes à être traitées. Il ne prend qu'un seul argument :
metadata
: objet contenant une cléTXXX
avec une valeur de chaîne associée préfixée pargoogle_
.
- processMetadata
Cette méthode planifie le traitement des chaînes de métadonnées par le SDK après le PTS spécifié. Elle utilise les arguments suivants :
type
: chaîne contenant le type d'événement en cours de traitement. Les valeurs acceptées sontID3
pour HLS ouurn:google:dai:2018
pour DASH.data
: valeur de chaîne préfixée pargoogle_
ou tableau d'octets suivant ce format :ID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
.timestamp
: code temporel en secondes auquel les données doivent être traitées.
Chaque type de flux compatible avec le SDK IMA DAI utilise une forme unique de métadonnées temporelles, comme décrit dans les sections suivantes.
Flux HLS MPEG2TS
Les flux HLS DAI linéaires utilisant les segments MPEG2TS transmettent les métadonnées temporelles au lecteur vidéo via des tags ID3 intégrés. Ces tags ID3 sont intégrés aux segments MPEG2TS et portent le nom de champ TXXX (pour le contenu textuel personnalisé défini par l'utilisateur).
Lecture dans Safari
Safari traite automatiquement les tags ID3 en tant que piste masquée. Les événements cuechange se déclenchent donc au bon moment pour traiter chaque élément de métadonnée. Vous pouvez transmettre toutes les métadonnées au SDK IMA DAI, quel que soit le contenu ou le type. Les métadonnées non pertinentes sont filtrées automatiquement.
Exemple :
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 fournit des tags ID3 par lots via l'événement FRAG_PARSING_METADATA
, sous forme de tableau d'échantillons. HLS.js ne traduit pas les données ID3 des tableaux d'octets en chaînes et ne décalent pas les événements vers leur PTS correspondant. Il n'est pas nécessaire de décoder les données d'exemple du tableau d'octets en chaîne ni de filtrer les tags ID3 non pertinents, car le SDK IMA DAI effectue ce décodage et ce filtrage automatiquement.
Exemple :
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Flux HLS CMAF
Les flux HLS DAI linéaires utilisant le Common Media Application Framework (CMAF) transmettent les métadonnées temporelles dans des boîtes eMSGv1 intégrées, conformément à la norme ID3 via CMAF. Ces zones eMSG sont intégrées au début de chaque segment multimédia, chaque eMSG ID3 contenant un PTS relatif à la dernière discontinuité du flux.
Depuis la version 1.2.0 de HLS.js, nos deux lecteurs suggérés transmettent les ID3 via CMAF à l'utilisateur comme s'il s'agissait de tags ID3. Pour cette raison, les exemples suivants sont les mêmes que pour les flux HLS MPEG2TS. Toutefois, cela peut ne pas être le cas avec tous les lecteurs. L'implémentation de la prise en charge des flux HLS CMAF peut donc nécessiter un code unique pour analyser les ID3 via eMSG.
Lecture dans Safari
Safari traite les métadonnées ID3 via eMSG comme des pseudo-événements ID3, en les fournissant par lots, automatiquement, en tant que piste masquée, de sorte que les événements cuechange sont déclenchés au bon moment pour traiter chaque élément de métadonnées. Vous pouvez transmettre toutes les métadonnées au SDK IMA DAI, qu'elles soient liées au timing ou non. Toutes les métadonnées non liées à l'insertion dynamique d'annonces sont automatiquement filtrées.
Exemple :
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
Depuis la version 1.2.0, HLS.js traite les métadonnées ID3 via eMSG comme des pseudo-événements ID3, en les fournissant par lots, via l'événement FRAG_PARSING_METADATA
, sous forme de tableau d'échantillons. HLS.js ne traduit pas les données ID3 des tableaux d'octets en chaînes et ne décalent pas les événements vers leur PTS correspondant. Il n'est pas nécessaire de décoder les exemples de données du tableau d'octets en chaîne, car le SDK IMA DAI effectue ce décodage automatiquement.
Exemple :
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Flux DASH
Les flux DASH DAI linéaires transmettent les métadonnées sous forme d'événements de manifeste dans un flux d'événements avec la valeur personnalisée schemeIdUri
urn:google:dai:2018
. Chaque événement de ces flux contient une charge utile de texte et le PTS.
DASH.js
Dash.js fournit des gestionnaires d'événements personnalisés nommés d'après la valeur schemeIdUri de chaque flux d'événements. Ces gestionnaires personnalisés se déclenchent par lots. Il vous appartient donc de traiter la valeur PTS pour synchroniser correctement l'événement. Le SDK IMA DAI peut gérer cela pour vous avec la méthode streamManager, processMetadata()
.
Exemple :
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);
});
...
Shaka Player
Shaka Player affiche les événements dans son événement timelineregionenter
. En raison d'une incompatibilité de format avec Shaka Player, la valeur des métadonnées doit être récupérée brute, via la propriété de détail eventNode.attributes['messageData']
.
Exemple :
player.addEventListener('timelineregionenter', function(event) {
const detail = event.detail;
if ( detail.eventNode.attributes &&
detail.eventNode.attributes['messageData']) {
const mediaId = detail.eventNode.attributes['messageData'];
const pts = detail.startTime;
streamManager.processMetadata("urn:google:dai:2018", mediaId, pts);
}
});
...
Diffusion de séries d'annonces
Pour la diffusion de pods, il existe différentes configurations pour transmettre les métadonnées temporelles en fonction des critères suivants :
- Type de flux en direct ou VOD
- Format de flux HLS ou DASH
- Le type de lecteur utilisé
- Type de backend DAI utilisé
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);
}
}