يوضّح هذا الدليل كيفية تشغيل بث مباشر أو فيديو عند الطلب (VOD) باستخدام ميزة "عرض مجموعة إعلانات" في "إدراج الإعلان الديناميكي"، وذلك من خلال حزمة تطوير البرامج (SDK) لتقنية IMA DAI لنظام HTML5 مع مشغّل فيديو يعتمد على hls.js للتشغيل. للاطّلاع على نموذج دمج مكتمل أو اتّباعه، مع إتاحة كلّ من HLS.js وSafari Playback، يمكنك الاطّلاع على مثال عرض مجموعة إعلانات HLS. للحصول على دعم DASH.js، يُرجى الاطّلاع على مثال عرض مجموعة إعلانات DASH. يمكنك تنزيل نماذج التطبيقات هذه من صفحة إصدار HTML5 DAI GitHub.
نظرة عامة على ميزة "عرض مجموعة إعلانات" في "إدراج الإعلان الديناميكي"
يتضمّن تنفيذ ميزة "عرض الإعلانات في مجموعات" باستخدام حزمة تطوير البرامج (SDK) لتقنية IMA DAI عنصرَين رئيسيَّين، وهما موضّحان في هذا الدليل:
PodStreamRequest/PodVodStreamRequest: عنصر يحدّد طلب بث إلى خوادم Google الإعلانية تحدّد الطلبات رمز الشبكة، وتتطلّبPodStreamRequestأيضًا مفتاح مادة عرض مخصّص ومفتاح واجهة برمجة تطبيقات اختياري. يتضمّن كلاهما مَعلمات اختيارية أخرى.
StreamManager: عنصر يعالج الاتصال بين بث الفيديو وحزمة تطوير البرامج (SDK) لتقنية "إدراج الإعلان الديناميكي" في "إعلانات الوسائط التفاعلية" (IMA DAI)، مثل تنشيط إشعارات التتبّع و إعادة توجيه أحداث البث إلى الناشر.
المتطلبات الأساسية
قبل البدء، تحتاج إلى ما يلي:
ثلاثة ملفات فارغة:
- dai.html
- dai.css
- dai.js
تثبيت Python على جهاز الكمبيوتر أو خادم ويب أو بيئة تطوير أخرى مستضافة لاستخدامها في الاختبار
ضبط بيئة تطوير
بما أنّ حزمة تطوير البرامج (SDK) تحمّل التبعيات باستخدام البروتوكول نفسه الذي تستخدمه الصفحة التي يتم تحميلها منها، عليك استخدام خادم ويب لاختبار تطبيقك. يمكنك بدء تشغيل خادم تطوير محلي بسرعة باستخدام خادم Python المضمّن.
باستخدام سطر أوامر، من الدليل الذي يحتوي على ملف
index.html، نفِّذ ما يلي:python -m http.server 8000في متصفّح الويب، انتقِل إلى
http://localhost:8000/يمكنك أيضًا استخدام أي بيئة تطوير أو خادم ويب مستضاف آخر، مثل خادم Apache HTTP.
إنشاء مشغّل فيديو
أولاً، عدِّل dai.html لإنشاء عنصر فيديو HTML5 وعنصر div لاستخدامهما في عناصر في واجهة المستخدم للإعلانات. أضِف أيضًا العلامات اللازمة لتحميل ملفَي dai.css وdai.js، بالإضافة إلى استيراد مشغّل الفيديو hls.js.
بعد ذلك، عدِّل dai.css لتحديد حجم عناصر الصفحة وموضعها.
أخيرًا، في dai.js، حدِّد المتغيّرات للاحتفاظ بمعلومات طلب البث
ودالة initPlayer() لتشغيلها عند تحميل الصفحة.
في ما يلي ثوابت طلبات البث:
BACKUP_STREAM: عنوان URL لبث احتياطي يتم تشغيله في حال حدوث خطأ فادح في عملية عرض الإعلانات
STREAM_URL: يُستخدَم فقط لأحداث البث المباشر. عنوان URL الخاص ببث الفيديو الذي يوفّره مُعدِّل ملفات البيان أو الشريك الخارجي الذي يستخدم ميزة "عرض الإعلانات في مجموعات" يجب أن يتطلب منك إدخال معرّف البث الذي توفّره حزمة تطوير البرامج (SDK) لتقنية IMA DAI قبل تقديم طلب. في هذه الحالة، يتضمّن عنوان URL للبث عنصرًا نائبًا،[[STREAMID]]، يتم استبداله بمعرّف البث قبل تقديم طلب.
NETWORK_CODE: رمز الشبكة لحسابك على "إدارة إعلانات Google 360"
CUSTOM_ASSET_KEY: يُستخدَم فقط لأحداث البث المباشر. مفتاح مادة العرض المخصّصة الذي يحدّد حدث عرض الإعلانات في مجموعات في "مدير إعلانات Google 360" ويمكن إنشاء هذه القيمة من خلال مُعدِّل ملفات البيان أو شريك خارجي في خدمة عرض الإعلانات المتتالية.
API_KEY: يُستخدَم فقط لأحداث البث المباشر. مفتاح واجهة برمجة تطبيقات اختياري يمكن أن يكون مطلوبًا لاسترداد معرّف بث من حزمة تطوير البرامج (SDK) لـ IMA DAI.
dai.html
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script src="dai.js"></script>
<link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
<h2>IMA DAI SDK Demo (HLS.JS)</h2>
<video id="video"></video>
<div id="adUi"></div>
</body>
</html>
dai.css
#video,
#adUi {
width: 640px;
height: 360px;
position: absolute;
top: 35px;
left: 0;
}
#adUi {
cursor: pointer;
}
dai.js
var BACKUP_STREAM =
'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'
// Stream Config.
const STREAM_URL = "";
const NETWORK_CODE = "";
const CUSTOM_ASSET_KEY = "";
const API_KEY = "";
var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
}
تحميل حزمة تطوير البرامج (SDK) لتقنية IMA DAI
بعد ذلك، أضِف إطار عمل "إدراج الإعلان الديناميكي" باستخدام علامة برمجية في dai.html، قبل علامة dai.js.
dai.html
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
<script src="dai.js"></script>
<link rel="stylesheet" href="dai.css" type="text/css">
</head>
...
بدء StreamManager وتقديم طلب بث مباشر أو فيديو عند الطلب
عرض مجموعة إعلانات البث المباشر
لطلب مجموعة من الإعلانات، أنشئ ima.dai.api.StreamManager، وهو المسؤول عن طلب وإدارة أحداث البث المباشر لإدراج الإعلانات الديناميكية. يأخذ الدالة الإنشائية عنصر فيديو، ويأخذ المثيل الناتج عنصر واجهة مستخدم للإعلان للتعامل مع التفاعلات مع الإعلانات.
بعد ذلك، حدِّد دالة لطلب البث المباشر لميزة "عرض الإعلانات المجمّعة". تنشئ هذه الدالة أولاً PodStreamRequest، وتضبطه باستخدام مَعلمات streamRequest المقدَّمة في الخطوة 2، ثم تستدعي streamManager.requestStream() باستخدام كائن الطلب هذا.
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestLivePodStream(NETWORK_CODE, CUSTOM_ASSET_KEY, API_KEY);
}
function requestLivePodStream(networkCode, customAssetKey, apiKey) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving live Stream Request
const streamRequest = new google.ima.dai.api.PodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.customAssetKey = customAssetKey;
streamRequest.apiKey = apiKey;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
عرض مجموعة إعلانات في الفيديوهات عند الطلب
لطلب مجموعة من الإعلانات، أنشئ ima.dai.api.StreamManager، وهو المسؤول عن طلب وإدارة أحداث البث المباشر لإدراج الإعلانات الديناميكية. يأخذ الدالة الإنشائية عنصر فيديو، ويأخذ المثيل الناتج عنصر واجهة مستخدم للإعلان للتعامل مع التفاعلات مع الإعلانات.
بعد ذلك، حدِّد دالة لطلب بث الفيديو عند الطلب من خلال ميزة "العرض في مجموعات". تنشئ هذه الدالة أولاً PodVodStreamRequest، وتضبطه باستخدام مَعلمات streamRequest المقدَّمة في الخطوة 2، ثم تستدعي streamManager.requestStream() باستخدام كائن الطلب هذا.
dai.js
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)
requestVodPodStream(NETWORK_CODE);
}
function requestVodPodStream(networkCode) {
// clear HLS.js instance, if in use
if (hls) {
hls.destroy();
}
// Generate a Pod Serving VOD Stream Request
const streamRequest = new google.ima.dai.api.PodVodStreamRequest();
streamRequest.networkCode = networkCode;
streamRequest.format = 'hls';
streamManager.requestStream(streamRequest);
}
التعامل مع أحداث البث
عرض مجموعة إعلانات البث المباشر
بعد ذلك، نفِّذ متتبِّعات الأحداث لأحداث الفيديو الرئيسية. يتعامل هذا المثال مع الأحداث STREAM_INITIALIZED وERROR وAD_BREAK_STARTED وAD_BREAK_ENDED من خلال استدعاء دالة onStreamEvent(). تتعامل هذه الدالة مع تحميل البث والأخطاء، بالإضافة إلى إيقاف عناصر التحكّم في المشغّل أثناء تشغيل الإعلان، وهو أمر مطلوب من حزمة تطوير البرامج (SDK). عند تحميل البث، يتم تحميل مشغّل الفيديو وتشغيل عنوان URL المقدَّم باستخدام دالة loadStream().
dai.js
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
onStreamEvent,
false);
...
function onStreamEvent(e) {
switch (e.type) {
case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
console.log('Stream initialized');
loadStream(e.getStreamData().streamId);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream('');
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
console.log('Ad Break Started');
isAdBreak = true;
videoElement.controls = false;
adUiElement.style.display = 'block';
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
console.log('Ad Break Ended');
isAdBreak = false;
videoElement.controls = true;
adUiElement.style.display = 'none';
break;
default:
break;
}
}
function loadStream(streamID) {
var url;
if(streamID) {
url = STREAM_URL.replace('[[STREAMID]]', streamID);
} else {
console.log('Stream Initialization Failed');
url = BACKUP_STREAM;
}
console.log('Loading:' + url);
hls.loadSource(url);
hls.attachMedia(videoElement);
}
عرض مجموعة إعلانات في الفيديوهات عند الطلب
بعد ذلك، نفِّذ متتبِّعات الأحداث لأحداث الفيديو الرئيسية. يتعامل هذا المثال مع الأحداث STREAM_INITIALIZED وLOADED وERROR وAD_BREAK_STARTED وAD_BREAK_ENDED من خلال استدعاء دالة onStreamEvent(). تتعامل هذه الدالة مع تحميل البث والأخطاء، بالإضافة إلى إيقاف عناصر التحكّم في المشغّل أثناء تشغيل الإعلان، وهو أمر مطلوب من حزمة تطوير البرامج (SDK).
بالإضافة إلى ذلك، تتطلّب أحداث بث "عرض مجموعة إعلانات الفيديو عند الطلب" استدعاء
StreamManager.loadStreamMetadata() استجابةً للحدث
STREAM_INITIALIZED. يجب أيضًا طلب عنوان URL للبث من
شريك تكنولوجيا الفيديو (VTP). بعد نجاح طلب loadStreamMetadata()، يتم تشغيل حدث LOADED، حيث يجب طلب دالة loadStream() باستخدام عنوان URL الخاص بالبث لتحميل البث وتشغيله.
var isAdBreak;
function initPlayer() {
videoElement = document.getElementById('video');
adUiElement = document.getElementById('adUi');
streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
streamManager.addEventListener(
[google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED,
google.ima.dai.api.StreamEvent.Type.ERROR,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
onStreamEvent,
false);
...
function onStreamEvent(e) {
switch (e.type) {
case google.ima.dai.api.StreamEvent.Type.STREAM_INITIALIZED:
const streamId = e.getStreamData().streamId;
// 'vtpInterface' is a place holder for your own video technology
// partner (VTP) API calls.
vtpInterface.requestStreamURL({
'streamId': streamId,
})
.then( (vtpStreamUrl) => {
streamUrl = vtpStreamUrl;
streamManager.loadStreamMetadata();
}, (error) => {
// Handle the error.
});
break;
case google.ima.dai.api.StreamEvent.Type.LOADED:
loadStream(streamUrl);
break;
case google.ima.dai.api.StreamEvent.Type.ERROR:
console.log('Error loading stream, playing backup stream.' + e);
loadStream();
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
console.log('Ad Break Started');
isAdBreak = true;
videoElement.controls = false;
adUiElement.style.display = 'block';
break;
case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
console.log('Ad Break Ended');
isAdBreak = false;
videoElement.controls = true;
adUiElement.style.display = 'none';
break;
default:
break;
}
}
function loadStream(url) {
if(url) {
console.log('Loading:' + url);
hls.loadSource(url);
} else {
console.log('Stream Initialization Failed');
hls.loadSource(BACKUP_STREAM);
}
hls.attachMedia(videoElement);
}
التعامل مع البيانات الوصفية للبث
في هذه الخطوة، عليك تنفيذ متتبِّعات الأحداث للبيانات الوصفية من أجل إعلام حزمة تطوير البرامج (SDK) عند وقوع أحداث الإعلانات. يمكن أن يختلف الاستماع إلى أحداث البيانات الوصفية أثناء عرض الإعلان، وذلك حسب تنسيق البث (HLS أو DASH) ونوع البث (بث مباشر أو فيديو عند الطلب) ونوع المشغّل ونوع الخلفية المستخدَمة في ميزة "إدراج الإعلان ديناميكيًا". لمزيد من المعلومات، يُرجى الاطّلاع على دليل البيانات الوصفية المحدّدة زمنيًا.
تنسيق بث HLS (أحداث البث المباشر والفيديوهات عند الطلب، مشغّل HLS.js)
إذا كنت تستخدم مشغّل HLS.js، استمِع إلى
حدث HLS.js FRAG_PARSING_METADATA للحصول على بيانات ID3 الوصفية وإرسالها إلى
حزمة تطوير البرامج (SDK) باستخدام StreamManager.processMetadata().
لتشغيل الفيديو تلقائيًا بعد تحميل كل المحتوى وتجهيزه، استمِع إلى حدث 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'
مرِّر البيانات الوصفية لـ ID3 إلى حزمة تطوير البرامج (SDK) باستخدام StreamManager.processMetadata().
لعرض عناصر التحكّم في الفيديو تلقائيًا بعد تحميل كل المحتوى وجاهزيته،
يمكنك الاستماع إلى حدث 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 Player مع أحداث البث المباشر (تنسيق بث DASH)
إذا كنت تستخدم مشغّل Shaka لتشغيل البث المباشر، استخدِم السلسلة '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 لتشغيل بث الفيديو عند الطلب، استخدِم السلسلة '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);
}
}
التعامل مع أحداث اللاعبين
أضِف متتبِّعات الأحداث إلى الحدثَين pause وstart لعنصر الفيديو للسماح
للمستخدم باستئناف التشغيل عندما تتوقف حزمة تطوير البرامج (SDK) مؤقتًا أثناء الفواصل الإعلانية.
function loadStream(streamUrl) {
...
videoElement.addEventListener('pause', onStreamPause);
videoElement.addEventListener('play', onStreamPlay);
}
function onStreamPause() {
console.log('paused');
if (isAdBreak) {
videoElement.controls = true;
adUiElement.style.display = 'none';
}
}
function onStreamPlay() {
console.log('played');
if (isAdBreak) {
videoElement.controls = false;
adUiElement.style.display = 'block';
}
}
حذف مواد عرض IMA DAI
عند الانتهاء بنجاح من طلب الإعلانات وعرضها في بث عرض الإعلانات المتعدّدة باستخدام حزمة تطوير البرامج (SDK) لتقنية IMA DAI، ننصحك بإزالة أي موارد بعد اكتمال جلسة عرض الإعلانات المتعدّدة. يمكنك استدعاء StreamManager.destroy() لإيقاف تشغيل البث وإيقاف تتبُّع الإعلانات وإصدار جميع مواد عرض البث التي تم تحميلها.
لمزيد من المعلومات حول ميزات حزمة تطوير البرامج (SDK) الأكثر تقدّمًا، يُرجى الاطّلاع على الأدلة الأخرى أو النماذج على GitHub.