लीनियर डीएआई स्ट्रीम में, तय समय के मेटाडेटा को मैनेज करना

इंटरैक्टिव मीडिया विज्ञापन (IMA) डाइनैमिक ऐड इंसर्शन (डीएआई) SDK टूल, स्ट्रीम के मीडिया सेगमेंट (इन-बैंड मेटाडेटा) में एम्बेड की गई मेटाडेटा की जानकारी या स्ट्रीमिंग मेनिफ़ेस्ट फ़ाइल (इन-मेनिफ़ेस्ट मेटाडेटा) में मौजूद मेटाडेटा की मदद से, दर्शकों के पोज़िशन और क्लाइंट-साइड विज्ञापन इवेंट को ट्रैक करता है. मेटाडेटा को अलग-अलग फ़ॉर्मैट में भेजा जाता है. यह इस बात पर निर्भर करता है कि स्ट्रीम किस तरह की है.

वीडियो प्लेयर को तय समय के हिसाब से मेटाडेटा बैच में मिलता है. प्लेयर के हिसाब से, मेटाडेटा को शेड्यूल किए गए समय पर या बैच में दिखाया जा सकता है. हर मेटाडेटा स्ट्रिंग में, प्रज़ेंटेशन का एक टाइमस्टैंप (पीटीएस) होता है जिससे यह पता चलता है कि उसे कब ट्रिगर किया जाना चाहिए.

मेटाडेटा को कैप्चर करने और उसे IMA डीएआई SDK टूल को फ़ॉरवर्ड करने की ज़िम्मेदारी आपके ऐप्लिकेशन की होती है. यह जानकारी भेजने के लिए, SDK टूल नीचे दिए गए तरीके उपलब्ध कराता है:

onTimedMetadata

यह तरीका, SDK टूल में प्रोसेस किए जाने के लिए तैयार मेटाडेटा स्ट्रिंग को फ़ॉरवर्ड करता है. इसमें सिर्फ़ एक तर्क की ज़रूरत होती है:

  • metadata: एक ऑब्जेक्ट जिसमें TXXX की कुंजी होती है और उससे जुड़ी स्ट्रिंग वैल्यू होती है जो google_ से शुरू होती है.
processMetadata

यह तरीका, मेटाडेटा स्ट्रिंग को शेड्यूल करता है, ताकि SDK टूल तय किए गए पीटीएस के बाद उन्हें प्रोसेस कर सके. इसके लिए ये तर्क ज़रूरी हैं:

  • type: प्रोसेस हो रहे इवेंट का टाइप दिखाने वाली स्ट्रिंग. स्वीकार किए जाने वाले वैल्यू, HLS के लिए ID3 या DASH के लिए urn:google:dai:2018 हैं
  • data: google_ से शुरू होने वाली स्ट्रिंग वैल्यू या ऐसी स्ट्रिंग को डिकोड करने वाला बाइट कलेक्शन.
  • timestamp: सेकंड में वह टाइमस्टैंप जब डेटा प्रोसेस होना चाहिए.

IMA डीएआई SDK टूल के साथ काम करने वाली हर तरह की स्ट्रीम, तय किए गए मेटाडेटा के खास रूप का इस्तेमाल करती है. इस बारे में नीचे दिए गए सेक्शन में बताया गया है.

HLS MPEG2TS स्ट्रीम

MPEG2TS सेगमेंट का इस्तेमाल करने वाली लीनियर डीएआई HLS स्ट्रीम, इन-बैंड आईडी3 टैग के ज़रिए वीडियो प्लेयर को टाइम्ड मेटाडेटा देती हैं. ये ID3 टैग MPEG2TS सेगमेंट में एम्बेड किए जाते हैं और इन्हें TXXX फ़ील्ड का नाम (उपयोगकर्ता के तय किए गए टेक्स्ट कॉन्टेंट के लिए) दिया जाता है.

Safari में प्लेबैक

Safari, ID3 टैग को एक छिपे हुए ट्रैक के रूप में अपने आप प्रोसेस करता है, इसलिए इवेंट को सही समय पर फ़ायर करें, ताकि मेटाडेटा के हर हिस्से को प्रोसेस किया जा सके. कॉन्टेंट या टाइप कुछ भी हो, सभी मेटाडेटा को IMA डीएआई 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 डेटा को बाइट अरे से स्ट्रिंग में अनुवाद नहीं करता है और इवेंट को उनसे जुड़े पीटीएस में ऑफ़सेट नहीं करता है. सैंपल डेटा को बाइट ऐरे से स्ट्रिंग में डिकोड करने या काम न करने वाले आईडी3 टैग को फ़िल्टर करने की ज़रूरत नहीं होती. इसकी वजह यह है कि IMA डीएआई SDK टूल, डेटा को डिकोड करने और फ़िल्टर करने के लिए अपने-आप काम करता है.

यहां एक उदाहरण दिया गया है:

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

HLS CMAF स्ट्रीम

लीनियर डीएआई HLS स्ट्रीम, कॉमन मीडिया ऐप्लिकेशन फ़्रेमवर्क (सीएमएएफ़) पास का इस्तेमाल करती है. इन-बैंड eMSGv1 बॉक्स के ज़रिए, टाइम्ड मेटाडेटा होती है. इस बॉक्स में, ID3 से लेकर CMAF स्टैंडर्ड तक की शर्तें होती हैं. ये eMSG बॉक्स हर मीडिया सेगमेंट की शुरुआत में एम्बेड किए जाते हैं और हर ID3 eMSG में स्ट्रीम में आखिरी बार की रुकावट के मुकाबले एक PTS होता है.

HLS.js के 1.2.0 वर्शन की रिलीज़ के हिसाब से, हमारे दोनों सुझाए गए प्लेयर, CMAF से आईडी3 को उपयोगकर्ता को पास करते हैं. इससे, ऐसा लगता है कि मानो वे ID3 टैग के तौर पर इस्तेमाल हो रहे हों. इस वजह से, यहां दिए गए उदाहरण HLS MPEG2TS स्ट्रीम के जैसे ही हैं. हालांकि, ऐसा हो सकता है कि सभी खिलाड़ियों के साथ ऐसा न हो, इसलिए HLS CMAF स्ट्रीम के लिए सपोर्ट लागू करने के लिए, eMSG के ज़रिए ID3 को पार्स करने के लिए एक यूनीक कोड की ज़रूरत हो सकती है.

Safari में प्लेबैक

Safari, eMSG मेटाडेटा के ज़रिए ID3 को pseudo ID3 इवेंट के रूप में देखता है. यह उन्हें बैच में अपने-आप, छिपे हुए ट्रैक के रूप में उपलब्ध कराता है, जैसे कि cuechange इवेंट, सही समय पर फ़ायर किए जाते हैं. इससे मेटाडेटा के हर हिस्से को प्रोसेस करने में मदद मिलती है. सभी मेटाडेटा को IMA डीएआई 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

वर्शन 1.2.0 के हिसाब से, HLS.js, eMSG मेटाडेटा से ID3 को नकली आईडी3 इवेंट के तौर पर देखता है. साथ ही, उन्हें FRAG_PARSING_METADATA इवेंट के ज़रिए बैच में उपलब्ध कराता है, जिसे सैंपल के तौर पर रखा गया है. HLS.js, ID3 डेटा को बाइट अरे से स्ट्रिंग में अनुवाद नहीं करता है और इवेंट को उनसे जुड़े पीटीएस में ऑफ़सेट नहीं करता है. सैंपल डेटा को बाइट अरे से स्ट्रिंग में डिकोड करना ज़रूरी नहीं है, क्योंकि IMA डीएआई 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 स्ट्रीम, कस्टम schemeIdUri वैल्यू urn:google:dai:2018 के साथ इवेंट स्ट्रीम में मेनिफ़ेस्ट इवेंट के रूप में मेटाडेटा पास करती हैं. इन स्ट्रीम के हर इवेंट में एक टेक्स्ट पेलोड और पीटीएस होता है.

DASH.js

Dash.js, हर इवेंट स्ट्रीम की स्कीमIdUri वैल्यू के आधार पर, कस्टम इवेंट हैंडलर उपलब्ध कराता है. ये कस्टम हैंडलर बैच में सक्रिय होते हैं, जिससे यह आपके ऊपर निर्भर करता है कि आप इवेंट को सही तरीके से पीटीएस मान को प्रोसेस कर सकते हैं. IMA डीएआई 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);
  }
});
...

पॉड सर्विंग

पॉड की सुविधा वाले मेटाडेटा के लिए, तय किए गए मेटाडेटा को पास करने के अलग-अलग कॉन्फ़िगरेशन होते हैं. ये कॉन्फ़िगरेशन इन शर्तों पर निर्भर करते हैं:

  • लाइव या वीओडी (वीडियो ऑन डिमांड) स्ट्रीम का टाइप
  • HLS या DASH स्ट्रीम फ़ॉर्मैट
  • इस्तेमाल किए जा रहे प्लेयर का टाइप
  • इस्तेमाल किया जा रहा डीएआई बैकएंड किस तरह का है

HLS स्ट्रीम फ़ॉर्मैट (लाइव और वीओडी स्ट्रीम, HLS.js प्लेयर)

अगर किसी HLS.js प्लेयर का इस्तेमाल किया जा रहा है, तो आईडी3 मेटाडेटा पाने के लिए, HLS.js FRAG_PARSING_METADATA इवेंट सुनें और उसे 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 स्ट्रीम का फ़ॉर्मैट, लाइव और वीओडी (वीडियो ऑन डिमांड) स्ट्रीम टाइप)

अगर DASH.js प्लेयर का इस्तेमाल किया जा रहा है, तो आपको लाइव या वीओडी स्ट्रीम के आईडी3 मेटाडेटा को सुनने के लिए, अलग-अलग स्ट्रिंग का इस्तेमाल करना होगा:

  • लाइव स्ट्रीम: 'https://developer.apple.com/streaming/emsg-id3'
  • वीओडी स्ट्रीम: 'urn:google:dai:2018'

StreamManager.processMetadata() की मदद से, SDK टूल को ID3 मेटाडेटा पास करें.

सब कुछ लोड और तैयार होने के बाद, वीडियो कंट्रोल अपने-आप दिखाने के लिए, 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);
}

लाइव स्ट्रीम के साथ शाका प्लेयर (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});
}

वीओडी स्ट्रीम के साथ Shaka Player (DASH स्ट्रीम फ़ॉर्मैट)

अगर वीओडी स्ट्रीम चलाने के लिए Shaka Player का इस्तेमाल किया है, तो मेटाडेटा इवेंट के बारे में जानने के लिए, 'timelineregionenter' स्ट्रिंग का इस्तेमाल करें. इसके बाद, 'urn:google:dai:2018' स्ट्रिंग के साथ StreamManager.processMetadata() को किए गए अपने कॉल में इवेंट के मैसेज के डेटा का इस्तेमाल करें.

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