Obsługa metadanych czasowych w liniowych strumieniach DAI

Pakiet SDK do dynamicznego wstawiania reklam (IMA) IMA SDK korzysta z informacji o metadanych umieszczonych w segmentach multimediów strumienia (metadane w pasku) lub w pliku manifestu (metadane w pliku manifestu), aby śledzić pozycję użytkowników i zdarzenia reklamowe po stronie klienta. Metadane są wysyłane w różnych formatach w zależności od typu odtwarzanego strumienia.

Odtwarzacz partiami otrzymuje metadane z sygnaturą czasową. W zależności od odtwarzacza metadane można wyświetlać w zaplanowanym czasie lub partiami. Z każdym ciągiem metadanych jest powiązana sygnatura czasowa prezentacji (PTS), która określa, kiedy ma zostać wywołane.

Twoja aplikacja jest odpowiedzialna za przechwytywanie metadanych i przekazywanie ich do pakietu IMA DAI SDK. Pakiet SDK udostępnia te metody przekazywania tych informacji:

onTimedMetadata

Ta metoda przekazuje do pakietu SDK ciągi metadanych, które są gotowe do przetworzenia. Przyjmuje jeden argument:

  • metadata: obiekt zawierający klucz TXXX z powiązaną wartością ciągu znaków, po której następuje google_.
processMetadata

Ta metoda planuje przetwarzanie ciągów metadanych do przetworzenia przez pakiet SDK po określonym czasie PTS. Przyjmuje te argumenty:

  • type: ciąg tekstowy zawierający typ przetwarzanego zdarzenia. Akceptowane wartości to ID3 w przypadku HLS i urn:google:dai:2018 w przypadku DASH
  • data: ciąg znaków poprzedzony ciągiem google_ lub tablica bajtów, która jest odkodowana do takiego ciągu.
  • timestamp: sygnatura czasowa w sekundach, w której dane powinny zostać przetworzone.

Każdy typ strumienia obsługiwany przez pakiet IMA DAI SDK używa unikalnej formy metadanych czasowych, co opisano w kolejnych sekcjach.

Strumienie HLS MPEG2TS

Liniowe strumienie HLS z dynamicznym wstawianiem reklam, używające segmentów MPEG2TS, przekazują metadane czasowe do odtwarzacza wideo za pomocą tagów ID3 w paśmie. Tagi ID3 są osadzone w segmentach MPEG2TS i mają nazwę pola TXXX (dla niestandardowego tekstu zdefiniowanego przez użytkownika).

Odtwarzanie w Safari

Safari przetwarza tagi ID3 automatycznie jako ukrytą ścieżkę, więc zdarzenia sygnału uruchamiają się w odpowiednim momencie, aby przetworzyć każdy fragment metadanych. Możesz przekazać do pakietu IMA DAI wszystkie metadane, niezależnie od treści czy typu. Nieistotne metadane są automatycznie odfiltrowywane.

Oto przykład:

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 udostępnia tagi ID3 partiami za pomocą zdarzenia FRAG_PARSING_METADATA w formie tablicy przykładów. HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków i nie kompensuje zdarzeń na odpowiadające im PTS. Nie trzeba dekodować przykładowych danych z tablicy bajtów do ciągu znaków ani odfiltrowywać niepowiązanych tagów ID3, ponieważ pakiet IMA DAI SDK automatycznie dekoduje i filtruje dane.

Oto przykład:

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

Strumienie HLS CMAF

Liniowe strumienie HLS z dynamicznym wstawianiem reklam, które używają platformy Common Media Application Framework (CMAF) przekazują metadane z włączonym czasem w paśmie eMSGv1 zgodnie ze standardem ID3 przez CMAF. Te pola eMSG są umieszczane na początku każdego segmentu multimediów, przy czym każda nieciągłość ID3 eMSG zawiera PTS względem ostatniej nieciągłości w strumieniu.

Od wersji 1.2.0 HLS.js obydwa sugerowane odtwarzacze przekazują użytkownikowi identyfikator 3 przez CMAF, tak jakby byli tagami ID3. Z tego powodu poniższe przykłady są takie same jak w przypadku strumieni HLS MPEG2TS. Nie musi to jednak dotyczyć wszystkich odtwarzaczy, więc wdrożenie obsługi strumieni HLS CMAF może wymagać unikalnego kodu do analizowania identyfikatorów ID3 za pomocą eMSG.

Odtwarzanie w Safari

Safari traktuje metadane ID3 za pomocą metadanych eMSG jako zdarzenia pseudo ID3, automatycznie udostępniając je partiami jako ukrytą ścieżkę. Zdarzenia cuechange są wywoływane w odpowiednim czasie, aby przetworzyć każdy fragment metadanych. Możesz przekazać do pakietu IMA DAI wszystkie metadane, niezależnie od tego, czy chodzi o czas czy nie. Wszystkie metadane niezwiązane z DAI są automatycznie odfiltrowywane.

Oto przykład:

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

Od wersji 1.2.0 HLS.js traktuje metadane ID3 i eMSG jako zdarzenia pseudo-ID3, udostępniając je partiami za pomocą zdarzenia FRAG_PARSING_METADATA jako tablicę przykładów. HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków i nie kompensuje zdarzeń na odpowiadające im PTS. Nie trzeba dekodować przykładowych danych z tablicy bajtów do ciągu znaków, ponieważ pakiet IMA DAI SDK wykonuje to dekodowanie automatycznie.

Oto przykład:

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

Strumienie DASH

W strumieniach liniowych DAI DASH z niestandardową wartością schemeIdUri urn:google:dai:2018 przekazywane są metadane w pliku manifestu w strumieniu zdarzeń. Każde zdarzenie w tych strumieniach zawiera ładunek tekstowy i obiekt PTS.

DASH.js

Dash.js udostępnia niestandardowe moduły obsługi zdarzeń, których nazwy pochodzą od wartości schema.org poszczególnych strumieni zdarzeń. Te niestandardowe moduły obsługi uruchamiają się partiami, pozostawiając Ci możliwość przetworzenia wartości PTS w celu odpowiedniego określenia czasu zdarzenia. Pakiet IMA DAI SDK może to dla Ciebie zrobić za pomocą metody streamManager (processMetadata()).

Oto przykład:

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

Odtwarzacz Shaka

Shaka Player wyświetla wydarzenia w ramach swoich wydarzeń timelineregionenter. Ze względu na niezgodność formatowania z Shaka Playerem wartość metadanych należy pobrać w postaci nieprzetworzonej za pomocą właściwości details eventElement.attributes['messageData'].value.

Oto przykład:

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

Blok reklamowy

W przypadku wyświetlania podów istnieją różne konfiguracje przekazywania metadanych czasowych, zależne od tych kryteriów:

  • Typ transmisji na żywo lub VOD
  • Format strumienia HLS lub DASH
  • typ używanego odtwarzacza.
  • Typ używanego backendu DAI

Format HLS (strumienie na żywo i VOD, odtwarzacz HLS.js)

Jeśli używasz odtwarzacza HLS.js, nasłuchuj zdarzenia FRAG_PARSING_METADATA HLS.js, aby pobrać metadane ID3 i przekaż je do pakietu SDK za pomocą StreamManager.processMetadata().

Jeśli chcesz automatycznie odtwarzać film, gdy wszystko zostanie załadowane i gotowe, nasłuchuj zdarzenia MANIFEST_PARSED HLS.js, które aktywuje odtwarzanie.

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 transmisji DASH, typ transmisji na żywo i VOD)

Jeśli używasz odtwarzacza DASH.js, w przypadku transmisji na żywo i VOD musisz używać innych ciągów znaków, aby wykrywać metadane ID3:

  • Transmisje na żywo: 'https://developer.apple.com/streaming/emsg-id3'
  • Strumienie VOD: 'urn:google:dai:2018'

Przekaż metadane ID3 do pakietu SDK za pomocą StreamManager.processMetadata().

Aby automatycznie wyświetlać elementy sterujące odtwarzaniem filmu, gdy wszystko zostanie wczytane i gotowe, wysłuchaj zdarzenia 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 z transmisjami na żywo (format transmisji DASH)

Jeśli korzystasz z odtwarzacza Shaka do odtwarzania transmisji na żywo, używaj ciągu 'emsg' do nasłuchiwania zdarzeń metadanych. Następnie użyj danych wiadomości o zdarzeniu w wywołaniu 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 ze strumieniami VOD (w formacie strumieni DASH)

Jeśli do odtwarzania strumienia VOD używasz odtwarzacza Shaka, do nasłuchiwania zdarzeń metadanych użyj ciągu 'timelineregionenter'. Następnie użyj danych komunikatu o zdarzeniu w wywołaniu StreamManager.processMetadata() z ciągiem znaków '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);
       }
}