處理線性 DAI 串流中的定時中繼資料

互動式媒體廣告 (IMA) 動態廣告插播 (DAI) SDK 仰賴 內嵌於串流媒體區段的中繼資料資訊 (頻內中繼資料) 或透過串流資訊清單檔案 (資訊清單中繼資料) 追蹤檢視者 位置和用戶端廣告事件中繼資料會以不同格式傳送 根據要播放的串流類型進行選擇

影片播放器會分批收到定時中繼資料。根據播放器 中繼資料則可能是在排定的時間或批次顯示每項中繼資料 字串有相關的顯示時間戳記 (PTS),表示

您的應用程式負責擷取中繼資料,並轉送至 IMA DAI SDK。SDK 提供下列方法來傳遞這項資訊:

onTimedMetadata

此方法會將已準備好處理的中繼資料字串 將機器學習工作流程自動化這個函式會採用單一引數:

  • metadata:這個物件包含 TXXX 的鍵,以及相關聯的字串 前置字串為 google_ 的前置字串。
processMetadata

此方法會將中繼資料字串排定在 指定的 PTS。可接受下列引數:

  • type:包含要處理事件類型的字串。已接受 值為 HLS 的 ID3,對 DASH 的值為 urn:google:dai:2018
  • data:開頭為 google_ 的字串值,或是每個 的解碼器會轉換成這類字串
  • timestamp:處理資料的時間戳記,以秒為單位。

IMA DAI SDK 支援的每種串流類型都會使用不重複的定時格式 中繼資料,

HLS MPEG2TS 串流

使用 MPEG2TS 片段的線性 DAI HLS 串流,將計時中繼資料傳送給 與影片播放器中的影片搭配使用這些 ID3 標記內嵌於 MPEG2TS 片段,並指定 TXXX 欄位名稱 (用於自訂的使用者定義文字) 內容)。

在 Safari 中播放影片

Safari 會自動處理 ID3 代碼做為隱藏追蹤,因此 cuechange 事件 並在正確時間觸發,處理每項中繼資料沒關係 所有中繼資料提交到 IMA DAI SDK 中 (無論內容或類型為何)。不相關 系統會自動篩除所有中繼資料

範例如下:

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 會透過 FRAG_PARSING_METADATA 事件批次提供 ID3 標記。 做為樣本陣列HLS.js 不會轉換位元組陣列中的 ID3 資料 不會使事件與對應的 PTS 重疊。這沒有 將範例資料從位元組陣列解碼為字串,或 不相關的 ID3 代碼,因為 IMA DAI SDK 會執行解碼及篩選 。

範例如下:

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

HTTP 即時串流 CMAF 串流

採用通用媒體應用程式架構 (CMAF) 傳遞的線性 DAI HLS 串流 透過頻內 eMSGv1 方塊 (網址:ID3 到 CMAF 標準。這些電子音樂盒 每個 ID3 eMSG 都嵌入 相對於串流上次中斷度的 PTS。

自 HLS.js 1.2.0 版推出後,我們建議兩個玩家都通過 ID3 視為透過 CMAF 回覆使用者,就像是 ID3 代碼一樣。因此, 下列範例與 HLS MPEG2TS 串流相同。不過 並非所有播放器都適用,因此請使用 HLS CMAF 支援功能 串流可能需要不重複的程式碼,才能透過 eMSG 剖析 ID3。

在 Safari 中播放影片

Safari 透過 eMSG 中繼資料將 ID3 視為虛擬 ID3 事件,在 批次處理,並顯示為隱藏軌跡,例如 cuechange 事件 並在處理每則中繼資料的正確時間時觸發可以 將所有中繼資料傳遞給 IMA DAI SDK (無論是否與時間相關)。不限 系統會自動篩除與 DAI 相關的中繼資料

範例如下:

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

自 1.2.0 版起,HLS.js 會將 ID3 透過 eMSG 中繼資料視為虛擬 ID3 透過 FRAG_PARSING_METADATA 事件批次提供這些事件。 做為樣本陣列HLS.js 不會轉換位元組陣列中的 ID3 資料 ,且不將事件偏移至相應的 PTS。這沒有 將範例資料從位元組陣列解碼為字串,因為 IMA DAI SDK 會自動執行解碼。

範例如下:

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

DASH 串流

線性 DAI DASH 串流會將中繼資料做為資訊清單事件,透過含有 自訂 schemeIdUriurn:google:dai:2018。這些條件中的每個事件 串流包含文字酬載和 PTS。

DASH.js

Dash.js 提供以每個 schemeIdUri 值命名的自訂事件處理常式 事件串流。這些自訂處理常式會分批觸發,完全由您自行啟動 會處理 PTS 值,以為事件正確時間。IMA DAI SDK 可處理 使用 streamManager 方法 processMetadata() 來建構。

範例如下:

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 會將事件顯示為 timelineregionenter 事件的一部分。應付款項 中繼資料值必須與 Shaka Player 不相容, 透過詳細資料屬性擷取原始資料 eventElement.attributes['messageData'].value

範例如下:

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

廣告連播放送

Pod 提供 中繼資料是否具有重大影響:

  • 直播或隨選影片串流類型
  • HLS 或 DASH 串流格式
  • 所用播放器的類型
  • 使用的 DAI 後端類型

HTTP 即時串流格式 (直播和隨選影片串流、HLS.js 播放器)

如果您使用 HLS.js 播放器,請 HLS.js FRAG_PARSING_METADATA 事件來取得 ID3 中繼資料,並傳遞至 使用 StreamManager.processMetadata() 的 SDK。

如要在所有內容載入並準備就緒後自動播放影片,請聆聽 觸發播放的 HLS.js MANIFEST_PARSED 事件。

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 (DASH 串流格式、直播和 VOD 串流類型)

如果您使用的是 DASH.js 播放器, 你必須使用不同字串來監聽直播或隨選影片的 ID3 中繼資料 串流:

  • 直播數:'https://developer.apple.com/streaming/emsg-id3'
  • VOD 串流數:'urn:google:dai:2018'

使用 StreamManager.processMetadata() 將 ID3 中繼資料傳遞至 SDK。

如要在載入內容並準備就緒後自動顯示影片控制項,請按照下列步驟操作: 監聽 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 播放器 (DASH 串流格式)

如果使用 Shaka Player 即時串流播放,請使用 'emsg' 字串來監聽中繼資料事件。 然後在對 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});
}

使用 VOD 串流的 Shaka 播放器 (DASH 串流格式)

如果使用 Shaka Player 播放 VOD 串流時,請使用 'timelineregionenter' 字串監聽 中繼資料事件接著,請在通話中使用事件訊息資料: StreamManager.processMetadata()敬上 字串為 '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);
       }
}