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

इंटरैक्टिव मीडिया विज्ञापन (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 स्ट्रीम में, इन-बैंड ID3 टैग के ज़रिए वीडियो प्लेयर को तय समय वाला मेटाडेटा भेजा जाता है. ये 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 स्ट्रीम में, कॉमन मीडिया ऐप्लिकेशन फ़्रेमवर्क (CMAF) पास का इस्तेमाल किया जाता है. साथ ही, इसमें इन-बैंड 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 को pseudo ID3 इवेंट के तौर पर देखता है. यह 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 स्ट्रीम

लीनियर डीएआई डैशबोर्ड स्ट्रीम, कस्टम schemeIdUri वैल्यू urn:google:dai:2018 के साथ इवेंट स्ट्रीम में मेनिफ़ेस्ट इवेंट के रूप में मेटाडेटा पास करती हैं. इन स्ट्रीम में हर इवेंट में एक टेक्स्ट पेलोड और पीटीएस शामिल होता है.

DASH.js

Dash.js, कस्टम इवेंट हैंडलर उपलब्ध कराता है, जिनका नाम, हर इवेंट स्ट्रीम की स्कीमIdUri की वैल्यू के आधार पर रखा जाता है. ये कस्टम हैंडलर बैच में सक्रिय होते हैं, जिससे इवेंट को सही तरीके से समय करने के लिए PTS मान को प्रोसेस करना आपके ऊपर निर्भर करता है. 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 प्लेयर का इस्तेमाल किया जा रहा है, तो आपको लाइव या वीओडी (वीडियो ऑन डिमांड) स्ट्रीम के लिए ID3 मेटाडेटा सुनने के लिए अलग-अलग स्ट्रिंग का इस्तेमाल करना होगा:

  • लाइव स्ट्रीम: '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);
}

लाइव स्ट्रीम के साथ Shaka प्लेयर (DASH स्ट्रीम फ़ॉर्मैट)

अगर लाइव स्ट्रीम चलाने के लिए शाका प्लेयर का इस्तेमाल किया जा रहा है, तो मेटाडेटा इवेंट सुनने के लिए '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 प्लेयर (DASH स्ट्रीम फ़ॉर्मैट)

अगर वीओडी (वीडियो ऑन डिमांड) स्ट्रीम चलाने के लिए, Shaka प्लेयर का इस्तेमाल किया जा रहा है, तो मेटाडेटा इवेंट सुनने के लिए '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);
       }
}