Menangani metadata dengan waktu

Pilih platform: HTML5 Roku

Interactive Media Ads (IMA) Dynamic Ad Insertion (DAI) SDK mengandalkan informasi metadata yang disematkan dalam segmen media streaming (metadata dalam band), atau dalam file manifes streaming (metadata dalam manifes) untuk melacak posisi penonton dan peristiwa iklan sisi klien. Metadata dikirim dalam format yang berbeda, bergantung pada jenis streaming yang diputar.

Pemutar video menerima metadata berwaktu dalam batch. Bergantung pada pemutar, metadata dapat ditampilkan pada waktu yang dijadwalkan, atau dalam batch. Setiap string metadata memiliki stempel waktu presentasi (PTS) terkait untuk waktu pemicuannya.

Aplikasi Anda bertanggung jawab untuk merekam metadata dan meneruskannya ke IMA DAI SDK. SDK menawarkan metode berikut untuk meneruskan informasi ini:

onTimedMetadata

Metode ini meneruskan string metadata yang siap diproses ke SDK. Fungsi ini menggunakan satu argumen:

  • metadata: objek yang berisi kunci TXXX dengan nilai string terkait yang diawali dengan google_.
processMetadata

Metode ini menjadwalkan string metadata untuk diproses oleh SDK setelah PTS yang ditentukan. Fungsi ini menggunakan argumen berikut:

  • type: string yang berisi jenis peristiwa yang sedang diproses. Nilai yang diterima adalah ID3 untuk HLS atau urn:google:dai:2018 untuk DASH
  • data: nilai string yang diawali dengan google_ atau array byte yang mengikuti format ini ID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx.
  • timestamp: stempel waktu dalam detik saat data harus diproses.

Setiap jenis streaming yang didukung oleh IMA DAI SDK menggunakan bentuk metadata berwaktu yang unik, seperti yang dijelaskan di bagian berikut.

Streaming HLS MPEG2TS

Streaming HLS DAI Linear menggunakan segmen MPEG2TS yang meneruskan metadata berwaktu ke pemutar video melalui tag ID3 dalam band. Tag ID3 ini disematkan dalam segmen MPEG2TS dan diberi nama kolom TXXX (untuk konten teks kustom yang ditentukan pengguna).

Pemutaran di Safari

Safari memproses tag ID3 secara otomatis, sebagai trek tersembunyi, sehingga peristiwa cuechange diaktifkan pada waktu yang tepat untuk memproses setiap bagian metadata. Anda boleh meneruskan semua metadata ke IMA DAI SDK, terlepas dari konten atau jenisnya. Metadata yang tidak relevan akan difilter secara otomatis.

Berikut contohnya:

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 menyediakan tag ID3 dalam batch melalui peristiwa FRAG_PARSING_METADATA, sebagai array sampel. HLS.js tidak menerjemahkan data ID3 dari array byte ke string dan tidak mengimbangi peristiwa ke PTS yang sesuai. Anda tidak perlu mendekode data contoh dari array byte ke string, atau memfilter tag ID3 yang tidak relevan, karena IMA DAI SDK melakukan dekode dan pemfilteran ini secara otomatis.

Berikut contohnya:

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

Streaming CMAF HLS

Streaming HLS DAI Linear yang menggunakan Common Media Application Framework (CMAF) meneruskan metadata berwaktu melalui kotak eMSGv1 dalam band sesuai dengan standar ID3 melalui CMAF. Kotak eMSG ini disematkan di awal setiap segmen media, dengan setiap eMSG ID3 berisi PTS relatif terhadap diskontinuitas terakhir dalam aliran.

Mulai rilis HLS.js 1.2.0, kedua pemutar yang kami sarankan meneruskan ID3 melalui CMAF kepada pengguna seolah-olah itu adalah tag ID3. Oleh karena itu, contoh berikut sama dengan contoh untuk streaming HLS MPEG2TS. Namun, hal ini mungkin tidak berlaku untuk semua pemutar, sehingga penerapan dukungan untuk streaming CMAF HLS mungkin memerlukan kode unik untuk mengurai ID3 melalui eMSG.

Pemutaran di Safari

Safari memperlakukan metadata ID3 melalui eMSG sebagai peristiwa pseudo ID3, yang memberikannya dalam batch, secara otomatis, sebagai trek tersembunyi, sehingga peristiwa cuechange diaktifkan pada waktu yang tepat untuk memproses setiap bagian metadata. Anda boleh meneruskan semua metadata ke IMA DAI SDK, baik yang relevan dengan pengaturan waktu maupun tidak. Semua metadata yang tidak terkait dengan DAI akan otomatis difilter.

Berikut contohnya:

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

Mulai versi 1.2.0, HLS.js memperlakukan ID3 melalui metadata eMSG sebagai peristiwa ID3 semu, yang menyediakannya dalam batch, melalui peristiwa FRAG_PARSING_METADATA, sebagai array sampel. HLS.js tidak menerjemahkan data ID3 dari array byte ke string dan tidak mengimbangi peristiwa ke PTS yang sesuai. Anda tidak perlu mendekode data contoh dari array byte ke string, karena IMA DAI SDK melakukan dekode ini secara otomatis.

Berikut contohnya:

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

Aliran DASH

Streaming DASH DAI linear meneruskan metadata sebagai peristiwa manifes dalam aliran peristiwa dengan nilai schemeIdUri kustom urn:google:dai:2018. Setiap peristiwa dalam aliran ini berisi payload teks dan PTS.

DASH.js

Dash.js menyediakan pengendali peristiwa kustom yang dinamai sesuai dengan nilai schemeIdUri dari setiap aliran peristiwa. Handler kustom ini diaktifkan dalam batch, sehingga Anda harus memproses nilai PTS untuk mengatur waktu peristiwa dengan benar. IMA DAI SDK dapat menangani hal ini untuk Anda, dengan metode streamManager, processMetadata().

Berikut contohnya:

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 menampilkan peristiwa sebagai bagian dari peristiwa timelineregionenter. Karena ketidakcocokan format dengan Shaka Player, nilai metadata harus diambil secara mentah, melalui properti detail eventNode.attributes['messageData'].

Berikut contohnya:

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

Penayangan pod

Untuk penayangan Pod, ada berbagai konfigurasi untuk meneruskan metadata yang disinkronkan waktu bergantung pada kriteria berikut:

  • Jenis streaming live atau VOD
  • Format streaming HLS atau DASH
  • Jenis pemutar yang digunakan
  • Jenis backend DAI yang digunakan

Format streaming HLS (Streaming Live dan VOD, pemutar HLS.js)

Jika Anda menggunakan pemutar HLS.js, dengarkan peristiwa FRAG_PARSING_METADATA HLS.js untuk mendapatkan metadata ID3 dan teruskan ke SDK dengan StreamManager.processMetadata().

Untuk memutar video secara otomatis setelah semuanya dimuat dan siap, dengarkan peristiwa MANIFEST_PARSED HLS.js untuk memicu pemutaran.

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 streaming DASH, jenis streaming Live dan VOD)

Jika Anda menggunakan pemutar DASH.js, Anda harus menggunakan string yang berbeda untuk memproses metadata ID3 untuk streaming Live atau VOD:

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

Teruskan metadata ID3 ke SDK dengan StreamManager.processMetadata().

Untuk menampilkan kontrol video secara otomatis setelah semuanya dimuat dan siap, dengarkan peristiwa DASH.js MANIFEST_LOADED.

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 dengan live stream (format streaming DASH)

Jika Anda menggunakan Shaka player untuk pemutaran livestream, gunakan string 'emsg' untuk memproses peristiwa metadata. Kemudian, gunakan data pesan peristiwa dalam panggilan Anda ke 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 dengan streaming VOD (format streaming DASH)

Jika Anda menggunakan Shaka player untuk pemutaran streaming VOD, gunakan string 'timelineregionenter' untuk memproses peristiwa metadata. Kemudian, gunakan data pesan peristiwa dalam panggilan ke StreamManager.processMetadata() dengan string '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);
       }
}