Obsługa metadanych czasowych w liniowych strumieniach DAI

Pakiet SDK interaktywnych reklam medialnych (IMA) do śledzenia pozycji użytkowników i zdarzeń reklamowych po stronie klienta korzysta z metadanych umieszczonych w segmentach multimediów strumienia (metadane w pasku) lub w pliku manifestu strumieniowania (metadane w pliku manifestu). Metadane są wysyłane w różnych formatach w zależności od typu odtwarzanej transmisji.

Odtwarzacz otrzymuje partiami metadane z sygnaturami czasowymi. W zależności od odtwarzacza metadane można udostępniać 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 odpowiada za przechwytywanie metadanych i przekazywanie ich do pakietu IMA DAI SDK. Pakiet SDK udostępnia te metody przekazywania tych informacji:

onTimedMetadata

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

  • metadata: obiekt zawierający klucz TXXX z powiązaną wartością ciągu znaków, poprzedzoną prefiksem 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. Akceptowane wartości to ID3 w przypadku HLS i urn:google:dai:2018 w przypadku DASH
  • data: ciąg znaków z przedrostkiem google_ lub tablica bajtów, która odkoduje taki ciąg znaków.
  • timestamp: sygnatura czasowa (w sekundach), w której należy przetworzyć dane.

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

Strumienie HLS MPEG2TS

Liniowe strumienie HLS HLS korzystające z segmentów MPEG2TS przekazują metadane czasowe do odtwarzacza wideo za pomocą tagów wewnątrz pasma ID3. Tagi ID3 są osadzone w segmentach MPEG2TS i otrzymują 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. Do pakietu IMA DAI SDK można przekazać wszystkie metadane, niezależnie od treści czy typu. Nietrafne 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 dostarcza tagi ID3 partiami za pomocą zdarzenia FRAG_PARSING_METADATA w formie tablicy przykładów. Biblioteka HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków i nie kompensuje zdarzeń do odpowiadających im PTS. Nie musisz dekodować przykładowych danych z tablicy bajtów na ciąg znaków ani odfiltrowywać niepowiązanych tagów ID3, ponieważ 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 HLS korzystające z platformy Common Media Application Framework (CMAF) przekazują metadane czasowe w paśmie eMSGv1 zgodnie ze standardem ID3 przez CMAF. Te pola eMSG są umieszczone na początku każdego segmentu multimediów, przy czym każda z parametrów ID3 eMSG zawiera parametr PTS odpowiadający ostatniej nieciągłości w strumieniu.

Od wersji 1.2.0 biblioteki HLS.js obydwa sugerowane odtwarzacze przekazują użytkownikowi identyfikator 3 przez CMAF, tak jakby to były tagi ID3. Z tego powodu poniższe przykłady są takie same jak w przypadku strumieni HLS MPEG2TS. Jednak nie musi tak być w przypadku niektórych odtwarzaczy, więc wdrożenie obsługi strumieni CMAF HLS może wymagać unikalnego kodu do analizowania ID3 przez eMSG.

Odtwarzanie w Safari

Safari traktuje metadane ID3 przez eMSG jako zdarzenia pseudo ID3, automatycznie udostępniając je partiami jako ukrytą ścieżkę. Dzięki temu zdarzenia cuechange są wywoływane w odpowiednim czasie w celu przetworzenia każdego fragmentu metadanych. Przekazywanie do pakietu IMA DAI SDK wszystkich metadanych, niezależnie od czasu, jest dozwolone. 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, udostępniając je partiami przez zdarzenie FRAG_PARSING_METADATA jako tablicę próbek. Biblioteka HLS.js nie tłumaczy danych ID3 z tablic bajtów na ciągi znaków i nie kompensuje zdarzeń do odpowiadających im PTS. Dekodowanie przykładowych danych z tablicy bajtów do ciągu znaków nie jest konieczne, 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 linearnych treści DASH z dynamicznym wstawianiem reklam metadane są przekazywane jako zdarzenia z pliku manifestu w strumieniu zdarzeń z niestandardową wartością schemeIdUri (urn:google:dai:2018). Każde zdarzenie w tych strumieniach zawiera ładunek tekstowy i obszar PTS.

DASH.js

Dash.js udostępnia niestandardowe moduły obsługi zdarzeń o nazwie odpowiadającej wartości schemaIdUri każdego strumienia zdarzeń. Te niestandardowe moduły obsługi uruchamiają się partiami, pozostawiając Ci możliwość przetworzenia wartości PTS w celu poprawnego przetworzenia 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 programem Shaka Player wartość metadanych musi zostać pobrana w postaci nieprzetworzonej za pomocą właściwości „detail” 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, które zależą od tych kryteriów:

  • Typ transmisji na żywo lub VOD
  • Format 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 HLS.js FRAG_PARSING_METADATA, aby pobrać metadane ID3 i przekazać je do pakietu SDK za pomocą StreamManager.processMetadata().

Aby automatycznie odtworzyć film, gdy wszystko zostanie załadowane i gotowe, aktywuj zdarzenie MANIFEST_PARSED HLS.js.

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 strumienia na żywo i VOD)

Jeśli używasz odtwarzacza DASH.js, musisz używać różnych ciągów znaków w celu nasłuchiwania metadanych ID3 w przypadku transmisji 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ą StreamManager.processMetadata().

Aby automatycznie wyświetlać elementy sterujące odtwarzaniem filmu, gdy wszystko zostanie wczytane i gotowe, włącz nasłuchiwanie 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);
}

Odtwarzacz Shaka z transmisjami na żywo (format strumieni DASH)

Jeśli do odtwarzania transmisji na żywo używasz odtwarzacza Shaka, do nasłuchiwania zdarzeń metadanych użyj ciągu 'emsg'. Następnie użyj tych danych w wywołaniu zdarzenia 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});
}

Odtwarzacz Shaka ze strumieniami VOD (format strumieni DASH)

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