SDK Chèn quảng cáo động (DAI) của Quảng cáo tương tác trên phương tiện truyền thông (IMA) dựa vào thông tin siêu dữ liệu được nhúng trong các phân đoạn nội dung nghe nhìn của luồng phát (siêu dữ liệu trong băng tần) hoặc trong tệp kê khai phát trực tuyến (siêu dữ liệu trong tệp kê khai) để theo dõi vị trí của người xem và các sự kiện quảng cáo phía máy khách. Siêu dữ liệu được gửi ở nhiều định dạng, tuỳ thuộc vào loại luồng phát.
Trình phát video nhận siêu dữ liệu có dấu thời gian theo lô. Tuỳ thuộc vào trình phát, siêu dữ liệu có thể xuất hiện tại thời điểm đã lên lịch hoặc theo đợt. Mỗi chuỗi siêu dữ liệu đều có một dấu thời gian trình bày (PTS) được liên kết cho biết thời điểm chuỗi đó sẽ được kích hoạt.
Ứng dụng của bạn chịu trách nhiệm thu thập siêu dữ liệu và chuyển tiếp siêu dữ liệu đó đến SDK DAI của IMA. SDK cung cấp các phương thức sau để truyền thông tin này:
- onTimedMetadata
Phương thức này chuyển tiếp các chuỗi siêu dữ liệu đã sẵn sàng để được xử lý đến SDK. Hàm này nhận một đối số duy nhất:
metadata
: một đối tượng chứa khoáTXXX
có giá trị chuỗi được liên kết và có tiền tố làgoogle_
.
- processMetadata
Phương thức này lên lịch để SDK xử lý các chuỗi siêu dữ liệu sau PTS được chỉ định. Hàm này nhận các đối số sau:
type
: một chuỗi chứa loại sự kiện đang được xử lý. Các giá trị được chấp nhận làID3
cho HLS hoặcurn:google:dai:2018
cho DASHdata
: một giá trị chuỗi có tiền tố làgoogle_
hoặc một mảng byte tuân theo định dạngID3:u\0004u\000u\000u\0000TXXXu\0004u\000u\000u\0000google_xxxxxxxx
.timestamp
: dấu thời gian tính bằng giây khi dữ liệu cần được xử lý.
Mỗi loại luồng được SDK IMA DAI hỗ trợ đều sử dụng một dạng siêu dữ liệu có dấu thời gian riêng, như mô tả trong các phần sau.
Luồng HLS MPEG2TS
Các luồng HLS DAI tuyến tính sử dụng các phân đoạn MPEG2TS truyền siêu dữ liệu có dấu thời gian đến trình phát video thông qua thẻ ID3 trong băng tần. Các thẻ ID3 này được nhúng trong các đoạn MPEG2TS và được đặt tên trường là TXXX (đối với nội dung văn bản tuỳ chỉnh do người dùng xác định).
Phát trong Safari
Safari tự động xử lý thẻ ID3 dưới dạng một bản nhạc ẩn, vì vậy, các sự kiện cuechange sẽ kích hoạt vào đúng thời điểm để xử lý từng phần siêu dữ liệu. Bạn có thể truyền tất cả siêu dữ liệu đến SDK DAI IMA, bất kể nội dung hoặc loại nào. Siêu dữ liệu không liên quan sẽ tự động bị lọc.
Ví dụ:
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 cung cấp các thẻ ID3 theo lô thông qua sự kiện FRAG_PARSING_METADATA
, dưới dạng một mảng mẫu. HLS.js không dịch dữ liệu ID3 từ mảng byte sang chuỗi và không bù đắp các sự kiện cho PTS tương ứng. Bạn không cần giải mã dữ liệu mẫu từ mảng byte thành chuỗi hoặc lọc ra các thẻ ID3 không liên quan, vì SDK IMA DAI sẽ tự động thực hiện việc giải mã và lọc này.
Ví dụ:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Luồng CMAF HLS
Các luồng HLS DAI tuyến tính sử dụng Khung ứng dụng đa phương tiện phổ biến (CMAF) truyền siêu dữ liệu có dấu thời gian thông qua các hộp eMSGv1 trong băng tần theo tiêu chuẩn ID3 thông qua CMAF. Các hộp eMSG này được nhúng ở đầu mỗi phân đoạn nội dung nghe nhìn, trong đó mỗi eMSG ID3 chứa một PTS tương ứng với điểm gián đoạn cuối cùng trong luồng.
Kể từ phiên bản 1.2.0 của HLS.js, cả hai trình phát được đề xuất của chúng tôi đều truyền ID3 thông qua CMAF cho người dùng như thể đó là thẻ ID3. Vì lý do này, các ví dụ sau đây cũng giống như đối với luồng HLS MPEG2TS. Tuy nhiên, điều này có thể không xảy ra với tất cả các trình phát, vì vậy, việc triển khai hỗ trợ cho các luồng HLS CMAF có thể yêu cầu mã riêng để phân tích cú pháp ID3 thông qua eMSG.
Phát trong Safari
Safari coi ID3 thông qua siêu dữ liệu eMSG là các sự kiện ID3 giả, cung cấp các sự kiện này theo lô, tự động, dưới dạng một bản nhạc ẩn, sao cho các sự kiện cuechange được kích hoạt vào đúng thời điểm để xử lý từng phần siêu dữ liệu. Bạn có thể truyền tất cả siêu dữ liệu đến SDK IMA DAI, cho dù siêu dữ liệu đó có liên quan đến thời gian hay không. Mọi siêu dữ liệu không liên quan đến DAI đều tự động bị lọc bỏ.
Ví dụ:
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
Kể từ phiên bản 1.2.0, HLS.js coi ID3 thông qua siêu dữ liệu eMSG là các sự kiện ID3 giả, cung cấp chúng theo lô, thông qua sự kiện FRAG_PARSING_METADATA
, dưới dạng một mảng mẫu. HLS.js không dịch dữ liệu ID3 từ mảng byte sang chuỗi và không bù sự kiện cho PTS tương ứng. Bạn không cần giải mã dữ liệu mẫu từ mảng byte thành chuỗi, vì SDK DAI IMA sẽ tự động thực hiện việc giải mã này.
Ví dụ:
hls.on(Hls.Events.FRAG_PARSING_METADATA, (e, data) => {
if (streamManager && data) {
data.samples.forEach((sample) => {
streamManager.processMetadata('ID3', sample.data, sample.pts);
});
}
});
...
Luồng DASH
Luồng DASH DAI tuyến tính truyền siêu dữ liệu dưới dạng các sự kiện tệp kê khai trong một luồng sự kiện có giá trị schemeIdUri
tuỳ chỉnh urn:google:dai:2018
. Mỗi sự kiện trong các luồng này đều chứa một tải trọng văn bản và PTS.
DASH.js
Dash.js cung cấp các trình xử lý sự kiện tuỳ chỉnh được đặt tên theo giá trị schemeIdUri của mỗi luồng sự kiện. Các trình xử lý tuỳ chỉnh này sẽ kích hoạt theo lô, bạn có thể xử lý giá trị PTS để tính thời gian chính xác cho sự kiện. IMA DAI SDK có thể xử lý việc này cho bạn bằng phương thức streamManager, processMetadata()
.
Ví dụ:
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 hiển thị các sự kiện trong sự kiện timelineregionenter
. Do không tương thích về định dạng với Shaka Player, nên bạn phải truy xuất giá trị siêu dữ liệu ở dạng thô thông qua thuộc tính chi tiết eventNode.attributes['messageData']
.
Ví dụ:
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);
}
});
...
Phân phát nhóm
Đối với việc phân phát Pod, có nhiều cấu hình để truyền siêu dữ liệu có dấu thời gian, tuỳ thuộc vào các tiêu chí sau:
- Loại luồng phát trực tiếp hoặc video theo yêu cầu
- Định dạng luồng HLS hoặc DASH
- Loại trình phát đang được sử dụng
- Loại phụ trợ DAI đang được sử dụng
Định dạng luồng HLS (Luồng phát trực tiếp và luồng VOD, trình phát HLS.js)
Nếu bạn đang sử dụng trình phát HLS.js, hãy lắng nghe sự kiện FRAG_PARSING_METADATA
HLS.js để nhận siêu dữ liệu ID3 và truyền siêu dữ liệu đó đến SDK bằng StreamManager.processMetadata()
.
Để tự động phát video sau khi mọi thứ đã tải xong và sẵn sàng, hãy theo dõi sự kiện MANIFEST_PARSED
HLS.js để kích hoạt chế độ phát.
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 (định dạng luồng DASH, loại luồng phát trực tiếp và VOD)
Nếu đang sử dụng trình phát DASH.js, bạn phải dùng các chuỗi khác nhau để theo dõi siêu dữ liệu ID3 cho luồng trực tiếp hoặc luồng VOD:
- Sự kiện phát trực tiếp:
'https://developer.apple.com/streaming/emsg-id3'
- Luồng VOD:
'urn:google:dai:2018'
Truyền siêu dữ liệu ID3 đến SDK bằng StreamManager.processMetadata()
.
Để tự động hiện các chế độ điều khiển video sau khi mọi thứ đã được tải và sẵn sàng, hãy lắng nghe sự kiện 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 có sự kiện phát trực tiếp (định dạng luồng DASH)
Nếu bạn đang sử dụng Trình phát Shaka để phát trực tiếp, hãy dùng chuỗi 'emsg'
để theo dõi các sự kiện siêu dữ liệu.
Sau đó, hãy sử dụng dữ liệu thông báo sự kiện trong lệnh gọi đến 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 có luồng VOD (định dạng luồng DASH)
Nếu bạn đang sử dụng trình phát Shaka để phát luồng VOD, hãy sử dụng chuỗi 'timelineregionenter'
để theo dõi các sự kiện siêu dữ liệu. Sau đó, hãy sử dụng dữ liệu thông báo sự kiện trong lệnh gọi đến StreamManager.processMetadata()
bằng chuỗi '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);
}
}