Obsługa metadanych czasowych

Wybierz platformę: HTML5 Roku

Pakiet SDK do dynamicznego wstawiania reklam (DAI) w interaktywnych reklamach multimedialnych (IMA) korzysta z informacji o metadanych osadzonych w segmentach multimedialnych strumienia (metadane w pasie) lub w pliku manifestu strumienia (metadane w manifeście), aby śledzić pozycje widzów i zdarzenia reklam po stronie klienta. Metadane są przesyłane w różnych formatach w zależności od typu odtwarzanego strumienia.

Odtwarzacz wideo otrzymuje metadane czasowe w partiach. W zależności od odtwarzacza metadane mogą być wyświetlane o zaplanowanej godzinie lub w partiach. Każdy ciąg metadanych ma powiązaną sygnaturę czasową prezentacji (PTS), która określa, kiedy ma zostać wywołany.

Aplikacja odpowiada za przechwytywanie metadanych i przekazywanie ich do pakietu IMA DAI SDK. Pakiet SDK oferuje te metody przekazywania tych informacji:

onTimedMetadata

Ta metoda przekazuje do pakietu SDK ciągi metadanych gotowe do przetworzenia. Przyjmuje 1 argument:

  • metadata: obiekt zawierający klucz TXXX z powiązaną wartością ciągu znaków, która ma prefiks google_.
processMetadata

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

  • type: ciąg znaków zawierający typ przetwarzanego zdarzenia. Dopuszczalne wartości to ID3 w przypadku HLS i urn:google:dai:2018 w przypadku DASH.
  • data: wartość ciągu znaków z prefiksem google_ lub tablica bajtów w tym formacie: ID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx.
  • timestamp: sygnatura czasowa w sekundach, kiedy dane powinny zostać przetworzone.

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

Strumienie HLS MPEG2TS

Strumienie HLS w przypadku liniowego DAI, które używają segmentów MPEG2TS, przekazują metadane czasowe do odtwarzacza wideo za pomocą tagów ID3 w pasmo. Te tagi ID3 są osadzone w segmentach MPEG2TS i mają nazwę pola TXXX (dla niestandardowej zawartości tekstowej zdefiniowanej przez użytkownika).

Odtwarzanie w Safari

Safari przetwarza tagi ID3 automatycznie jako ukryty ścieżkę, więc zdarzenia cuechange są wywoływane w odpowiednim czasie, aby przetworzyć każdy element metadanych. Możesz przekazywać do pakietu IMA DAI SDK 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

Biblioteka HLS.js udostępnia tagi ID3 w partiach za pomocą zdarzenia FRAG_PARSING_METADATA w postaci tablicy próbek. HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków ani nie przesuwa zdarzeń do odpowiadających im znaczników PTS. Nie musisz dekodować danych próbnych z tablicy bajtów do ciągu znaków ani odfiltrowywać nieistotnych tagów ID3, ponieważ pakiet IMA DAI SDK wykonuje to dekodowanie i filtrowanie 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 HLS CMAF

Strumienie HLS DAI linearne korzystające z Common Media Application Framework (CMAF) przekazują metadane czasowe za pomocą pól eMSGv1 w paśmie zgodnie ze standardem ID3 przez CMAF. Te pola eMSG są osadzone na początku każdego segmentu multimedialnego, a każde pole ID3 eMSG zawiera znacznik PTS względny w stosunku do ostatniej nieciągłości w strumieniu.

Od wersji 1.2.0 biblioteki HLS.js oba sugerowane przez nas odtwarzacze przekazują ID3 przez CMAF do użytkownika tak, jakby były to tagi ID3. Z tego powodu poniższe przykłady są takie same jak w przypadku strumieni HLS MPEG2TS. Nie musi tak jednak być w przypadku wszystkich odtwarzaczy, więc wdrożenie obsługi strumieni HLS CMAF może wymagać unikalnego kodu do analizowania ID3 za pomocą eMSG.

Odtwarzanie w Safari

Safari traktuje metadane ID3 i eMSG jako zdarzenia pseudo-ID3, udostępniając je automatycznie w pakietach jako ukrytą ścieżkę, dzięki czemu zdarzenia cuechange są wywoływane w odpowiednim czasie, aby przetworzyć każdy fragment metadanych. Możesz przekazywać do pakietu IMA DAI SDK wszystkie metadane, niezależnie od tego, czy są one związane z czasem. Wszelkie 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 przez eMSG jako zdarzenia pseudo ID3, dostarczając je w partiach za pomocą zdarzenia FRAG_PARSING_METADATA jako tablicę próbek. HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków ani nie przesuwa zdarzeń do odpowiadających im znaczników PTS. Nie musisz dekodować przykładowych danych z tablicy bajtów na ciąg znaków, ponieważ pakiet IMA DAI SDK robi to 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

Strumienie DASH w przypadku liniowego DAI przekazują metadane jako zdarzenia manifestu w strumieniu zdarzeń z niestandardową wartością schemeIdUriurn:google:dai:2018. Każde zdarzenie w tych strumieniach zawiera ładunek tekstowy i sygnaturę czasową.

DASH.js

Dash.js udostępnia niestandardowe moduły obsługi zdarzeń o nazwach zgodnych z wartością schemeIdUri każdego strumienia zdarzeń. Te niestandardowe funkcje obsługi są uruchamiane partiami, więc to Ty musisz przetworzyć wartość PTS, aby prawidłowo określić czas zdarzenia. Pakiet IMA DAI SDK może to zrobić za Ciebie 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);
});
...

Shaka Player

Shaka Player udostępnia zdarzenia w ramach zdarzenia timelineregionenter. Ze względu na niezgodność formatowania z Shaka Player wartość metadanych musi być pobierana w formacie surowym za pomocą właściwości szczegółów eventNode.attributes['messageData'].

Oto przykład:

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

Wyświetlanie bloków reklamowych

W przypadku wyświetlania w ramach Pod istnieją różne konfiguracje przekazywania metadanych czasowych w zależności od tych kryteriów:

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

Format strumienia 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 uzyskać metadane ID3, i przekaż je do pakietu SDK za pomocą funkcji StreamManager.processMetadata().

Aby automatycznie odtworzyć film po załadowaniu i przygotowaniu wszystkich elementów, nasłuchuj zdarzenia MANIFEST_PARSED HLS.js, aby wywołać 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 strumieni DASH, typ strumienia na żywo i VOD)

Jeśli używasz odtwarzacza DASH.js, musisz użyć różnych ciągów znaków, aby nasłuchiwać metadanych ID3 w przypadku strumieni na żywo lub VOD:

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

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

Aby automatycznie wyświetlać elementy sterujące odtwarzaniem po załadowaniu i przygotowaniu wszystkich elementów, nasłuchuj 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 strumieni DASH)

Jeśli do odtwarzania transmisji na żywo używasz odtwarzacza Shaka, użyj ciągu znaków 'emsg', aby nasłuchiwać zdarzeń metadanych. Następnie użyj danych z 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 (format strumieni DASH)

Jeśli do odtwarzania strumienia VOD używasz odtwarzacza Shaka, użyj ciągu 'timelineregionenter', aby nasłuchiwać zdarzeń metadanych. Następnie użyj danych z wiadomości o zdarzeniu w wywołaniu funkcji 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);
       }
}