SDK โฆษณาสื่ออินเทอร์แอกทีฟ (IMA) สำหรับการแทรกโฆษณาแบบไดนามิก (DAI) อาศัย ข้อมูลเมตาที่ฝังอยู่ในกลุ่มสื่อของสตรีม (ข้อมูลเมตาในแบนด์) หรือในไฟล์ Manifest ของการสตรีม (ข้อมูลเมตาใน Manifest) เพื่อติดตามตำแหน่งของผู้ชม และเหตุการณ์โฆษณาฝั่งไคลเอ็นต์ ระบบจะส่งข้อมูลเมตาในรูปแบบต่างๆ โดยขึ้นอยู่กับประเภทของสตรีมที่เล่น
วิดีโอเพลเยอร์จะได้รับข้อมูลเมตาที่กำหนดเวลาเป็นชุด โดยข้อมูลเมตาจะแสดงตามเวลาที่กำหนดหรือเป็นชุด ทั้งนี้ขึ้นอยู่กับเพลเยอร์ สตริงข้อมูลเมตาแต่ละรายการ มีการประทับเวลาของการนำเสนอ (PTS) ที่เชื่อมโยงกันสำหรับเวลาที่ควร ทริกเกอร์
แอปของคุณมีหน้าที่บันทึกข้อมูลเมตาและส่งต่อข้อมูลไปยัง IMA DAI SDK SDK มีเมธอดต่อไปนี้เพื่อส่งข้อมูลนี้
- onTimedMetadata
เมธอดนี้จะส่งต่อสตริงข้อมูลเมตาที่พร้อมประมวลผลไปยัง SDK โดยรับอาร์กิวเมนต์เดียว
metadata
: ออบเจ็กต์ที่มีคีย์ของTXXX
พร้อมค่าสตริงที่เชื่อมโยง ซึ่งมีคำนำหน้าเป็นgoogle_
- processMetadata
เมธอดนี้จะกำหนดเวลาให้ SDK ประมวลผลสตริงข้อมูลเมตาหลังจาก PTS ที่ระบุ โดยจะรับอาร์กิวเมนต์ต่อไปนี้
type
: สตริงที่มีประเภทของเหตุการณ์ที่กำลังประมวลผล ค่าที่ยอมรับ คือID3
สำหรับ HLS หรือurn:google:dai:2018
สำหรับ DASHdata
: ค่าสตริงที่นำหน้าด้วยgoogle_
หรืออาร์เรย์ไบต์ที่ เป็นไปตามรูปแบบนี้ID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
timestamp
: การประทับเวลาเป็นวินาทีเมื่อควรประมวลผลข้อมูล
สตรีมแต่ละประเภทที่ IMA DAI SDK รองรับจะใช้รูปแบบข้อมูลเมตาแบบกำหนดเวลาที่ไม่ซ้ำกันตามที่อธิบายไว้ในส่วนต่อไปนี้
สตรีม HLS MPEG2TS
สตรีม HLS ของ DAI เชิงเส้นที่ใช้กลุ่ม MPEG2TS จะส่งข้อมูลเมตาที่กำหนดเวลาไปยัง วิดีโอเพลเยอร์ผ่านแท็ก ID3 ในแบนด์ แท็ก 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 จะให้แท็ก ID3 เป็นชุดผ่านเหตุการณ์ FRAG_PARSING_METADATA
เป็นอาร์เรย์ของตัวอย่าง 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);
});
}
});
...
สตรีม HLS CMAF
สตรีม HLS ของ DAI แบบเชิงเส้นที่ใช้ Common Media Application Framework (CMAF) จะส่งข้อมูลเมตาที่มีการกำหนดเวลาผ่านกล่อง eMSGv1 แบบ In-band ตามมาตรฐาน ID3 ผ่าน CMAF กล่อง eMSG เหล่านี้จะ ฝังอยู่ที่จุดเริ่มต้นของแต่ละกลุ่มสื่อ โดย eMSG ของ ID3 แต่ละรายการจะมี PTS ที่สัมพันธ์กับการหยุดชะงักครั้งล่าสุดในสตรีม
ตั้งแต่ HLS.js เวอร์ชัน 1.2.0 เป็นต้นมา เพลเยอร์ที่แนะนำทั้ง 2 รายการจะส่ง ID3 ผ่าน CMAF ไปยังผู้ใช้ราวกับว่าเป็นแท็ก ID3 ด้วยเหตุนี้ ตัวอย่างต่อไปนี้จึงเหมือนกับตัวอย่างสำหรับสตรีม HLS MPEG2TS อย่างไรก็ตาม เพลเยอร์บางรายอาจไม่เป็นเช่นนั้น ดังนั้นการรองรับสตรีม HLS CMAF อาจต้องใช้โค้ดที่ไม่ซ้ำกันเพื่อแยกวิเคราะห์ ID3 ผ่าน eMSG
การเล่นใน Safari
Safari จะถือว่า ID3 ผ่านข้อมูลเมตา eMSG เป็นเหตุการณ์ 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
สตรีม DASH ของ DAI เชิงเส้นจะส่งข้อมูลเมตาเป็นเหตุการณ์ในไฟล์ Manifest ในสตรีมเหตุการณ์ที่มี
schemeIdUri
ค่าurn: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
Shaka Player จะแสดงเหตุการณ์เป็นส่วนหนึ่งของtimelineregionenter
event เนื่องจากรูปแบบไม่เข้ากันกับ Shaka Player คุณจึงต้องดึงค่าข้อมูลเมตาแบบดิบผ่านพร็อพเพอร์ตี้รายละเอียด eventNode.attributes['messageData']
เช่น
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);
}
});
...
การแสดงในพ็อด
สำหรับการแสดงพ็อด จะมีการกำหนดค่าที่แตกต่างกันสำหรับการส่งต่อข้อมูลเมตาที่กำหนดเวลา โดยขึ้นอยู่กับเกณฑ์ต่อไปนี้
- ประเภทสตรีมแบบสดหรือ VOD
- รูปแบบสตรีม HLS หรือ DASH
- ประเภทของเพลเยอร์ที่ใช้
- ประเภทของแบ็กเอนด์ DAI ที่ใช้
รูปแบบสตรีม HLS (สตรีมแบบสดและ VOD, โปรแกรมเล่น HLS.js)
หากคุณใช้เพลเยอร์ HLS.js ให้ฟังเหตุการณ์ FRAG_PARSING_METADATA
ของ HLS.js เพื่อรับข้อมูลเมตา ID3 และส่งไปยัง SDK ด้วย StreamManager.processMetadata()
หากต้องการเล่นวิดีโอโดยอัตโนมัติหลังจากโหลดทุกอย่างเสร็จสิ้นและพร้อมใช้งาน ให้ฟังเหตุการณ์ 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 (รูปแบบสตรีม DASH, ประเภทสตรีมแบบสดและ VOD)
หากใช้เพลเยอร์ DASH.js คุณต้องใช้สตริงอื่นเพื่อฟังข้อมูลเมตา ID3 สำหรับสตรีมสดหรือ VOD
- ไลฟ์สด:
'https://developer.apple.com/streaming/emsg-id3'
- สตรีม VOD:
'urn:google:dai:2018'
ส่งข้อมูลเมตา ID3 ไปยัง SDK ด้วย StreamManager.processMetadata()
หากต้องการแสดงตัวควบคุมวิดีโอโดยอัตโนมัติหลังจากโหลดทุกอย่างเสร็จสิ้นและพร้อมใช้งาน ให้
ฟังเหตุการณ์ 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);
}
Shaka Player ที่มีไลฟ์สด (รูปแบบสตรีม 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 ที่มีสตรีม VOD (รูปแบบสตรีม 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);
}
}