تسهّل حِزم تطوير البرامج (SDK) لإعلانات الوسائط التفاعلية دمج إعلانات الوسائط المتعددة في مواقعك الإلكترونية وتطبيقاتك. يمكن لحِزم تطوير البرامج لإعلانات الوسائط التفاعلية طلب الإعلانات من أي خادم إعلانات متوافق مع VAST وإدارة تشغيل الإعلانات في تطبيقاتك. باستخدام حِزم تطوير البرامج لإدراج الإعلانات الديناميكي في "إعلانات الوسائط التفاعلية"، تقدّم التطبيقات طلب بث لإعلان وفيديو محتوى، سواء كان فيديو عند الطلب أو محتوى مباشرًا. بعد ذلك، تعرض حزمة SDK بث فيديو مدمجًا، ما يغنيك عن إدارة التبديل بين الفيديو الإعلاني والفيديو الخاص بالمحتوى داخل تطبيقك.
اختيار حلّ "الإعلانات الديناميكية أثناء عرض الفيديو" الذي يهمّك
إدراج إعلان ديناميكي في البودكاست
يوضّح هذا الدليل كيفية تشغيل بث "عرض الإعلانات المتسلسلة" في "الإعلانات الديناميكية أثناء عرض الفيديو" لمحتوى مباشر أو محتوى عند الطلب، وذلك باستخدام حزمة تطوير البرامج للإعلانات الديناميكية أثناء عرض الفيديو من "إعلانات الوسائط التفاعلية" في HTML5 مع مشغّل فيديو يعتمد على hls.js للتشغيل. للاطّلاع على مثال على عملية دمج مكتملة تتوافق مع كل من HLS.js وSafari Playback، يُرجى الاطّلاع على مثال على عرض إعلانات البودكاست باستخدام HLS. للحصول على معلومات حول توافق DASH.js، يُرجى الاطّلاع على مثال على عرض الإعلانات في حزمة DASH. يمكنك تنزيل هذه التطبيقات النموذجية من صفحة إصدار HTML5 DAI على GitHub.
نظرة عامة حول عرض "حزم إعلانات" في ميزة "إدراج الإعلان الديناميكي"
يتضمّن تنفيذ ميزة "عرض الإعلانات المتسلسلة" باستخدام حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA) من أجل "الإعلانات الرقمية المباشرة" مكوّنَين رئيسيَّين، وهما موضّحان في هذا الدليل:
PodStreamRequest
/PodVodStreamRequest
: عنصر يحدّد طلب بث إلى خوادم Google الإعلانية. تحدّد الطلبات رمز شبكة، ويتطلّبPodStreamRequest
أيضًا مفتاح أصول مخصّص ومفتاح واجهة برمجة تطبيقات اختياريًا. يتضمّن كلاهما مَعلمات اختيارية أخرى.StreamManager
: عنصر يعالج التواصل بين بث الفيديو و"حزمة تطوير البرامج (SDK) للإعلانات الديناميكية أثناء عرض الفيديو" من "إعلانات الوسائط التفاعلية"، مثل إرسال إشارات تتبُّع وإعادة توجيه أحداث البث إلى الناشر.
المتطلبات الأساسية
قبل البدء، يجب أن يتوفّر لديك ما يلي:
ثلاثة ملفات فارغة:
- 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 لتدفق الفيديو المقدَّم من خلال أداة معالجة ملف البيان أو شريك خارجي يستخدم ميزة "عرض الإعلانات ضمن حزمة". يجب أن يطلب منك إدخال معرّف البث الذي توفّره حزمة تطوير البرامج لإعلانات الوسائط التفاعلية (IMA) الخاصة بميزة "الإعلانات الديناميكية أثناء البث"، وذلك قبل تقديم طلب. في هذه الحالة، يتضمّن عنوان URL للبث عنصرًا نائبًا،[[STREAMID]]
، يتم استبداله بمعرّف البث قبل إرسال الطلب.NETWORK_CODE
: رمز الشبكة لحسابك على "مدير إعلانات Google 360".
CUSTOM_ASSET_KEY
: تُستخدم فقط لفيديوهات البث المباشر. مفتاح العنصر المخصّص الذي يحدّد حدث عرض حزمة إعلانية في "مدير إعلانات Google" 360. يمكن إنشاء هذا الملف من خلال أداة تعديل ملف البيان أو شريك خارجي يقدّم خدمة Pod Serving.
API_KEY
: تُستخدم فقط لفيديوهات البث المباشر. مفتاح API اختياري يمكن أن يكون مطلوبًا لاسترداد معرّف بث من حزمة تطوير البرامج لإدراج الإعلان الديناميكي في "إعلانات الوسائط التفاعلية".
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');
}
تحميل حزمة تطوير البرامج لإدراج إعلان ديناميكي من "إعلانات الوسائط التفاعلية"
بعد ذلك، أضِف إطار عمل 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
، وهو المسؤول عن طلب وإدارة بث DAI. يأخذ الدالّة الإنشائية عنصر فيديو، ويأخذ المثال الناتج عنصر واجهة مستخدم للإعلان من أجل معالجة التفاعلات مع الإعلان.
بعد ذلك، حدِّد دالة لطلب البث المباشر من Pod Serving. تنشئ هذه الدالة أولاً 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
، وهو المسؤول عن طلب وإدارة بث DAI. يأخذ الدالّة الإنشائية عنصر فيديو، ويأخذ المثال الناتج عنصر واجهة مستخدم للإعلان من أجل معالجة التفاعلات مع الإعلان.
بعد ذلك، حدِّد دالة لطلب بث VOD من "إعلانات ضمن البود". تنشئ هذه الدالة أولاً 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()
. تتعامل هذه الدالة مع تحميل البث والأخطاء، بالإضافة إلى إيقاف عناصر التحكّم في المشغّل أثناء عرض الإعلان، وهو أمر مطلوب من حزمة تطوير البرامج.
بالإضافة إلى ذلك، تتطلّب عمليات بث VOD Pod Serving استدعاء 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، استمع إلى حدث 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، ونوع بث مباشر وفيديو عند الطلب)
إذا كنت تستخدم مشغّل DASH.js، عليك استخدام سلاسل مختلفة للاستماع إلى البيانات الوصفية ID3 لبث مباشر أو بث عند الطلب:
- أحداث البث المباشر:
'https://developer.apple.com/streaming/emsg-id3'
- مصادر الفيديوهات عند الطلب:
'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 مع فيديوهات متوفرة عند الطلب (تنسيق فيديوهات DASH)
إذا كنت تستخدم Shaka player لتشغيل بث الفيديو عند الطلب، استخدِم السلسلة '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
عند الانتهاء بنجاح من طلب الإعلانات وعرضها في بث "عرض الإعلانات المتسلسلة" باستخدام حزمة تطوير البرامج IMA DAI، ننصحك بتنظيف أي موارد بعد اكتمال جلسة "عرض الإعلانات المتسلسلة". اتّصِل بالرقم StreamManager.destroy()
لإيقاف تشغيل البث
وإيقاف جميع عمليات تتبُّع الإعلانات وإصدار جميع مواد عرض البث التي تم تحميلها.
للاطّلاع على المزيد من ميزات حزمة تطوير البرامج المتقدّمة، راجِع الأدلة الأخرى أو الأمثلة على GitHub.