إعداد حزمة تطوير البرامج لإعلانات الوسائط التفاعلية لعرض الإعلانات أثناء التشغيل

اختيار النظام الأساسي: HTML5 Android iOS tvOS Cast Roku

تسهّل حِزم تطوير البرامج (SDK) لإعلانات الوسائط التفاعلية دمج إعلانات الوسائط المتعددة في مواقعك الإلكترونية وتطبيقاتك. يمكن لحِزم تطوير البرامج لإعلانات الوسائط التفاعلية طلب الإعلانات من أي خادم إعلانات متوافق مع VAST وإدارة تشغيل الإعلانات في تطبيقاتك. باستخدام حِزم تطوير البرامج (SDK) الخاصة بميزة "إدراج الإعلان الديناميكي" في "إعلانات الوسائط التفاعلية" (IMA DAI)، تقدّم التطبيقات طلب بث لإعلان وفيديو محتوى، سواء كان فيديو عند الطلب أو محتوى مباشرًا. بعد ذلك، تعرض حزمة SDK بث فيديو مدمجًا، ما يغنيك عن إدارة التبديل بين الفيديو الإعلاني وفيديو المحتوى داخل تطبيقك.

اختيار حلّ "الإعلانات الديناميكية داخل الفيديو" الذي يهمّك

Pod Serving DAI

يوضّح هذا الدليل كيفية تشغيل بثّ "عرض الإعلانات في حزمة" باستخدام تكنولوجيا "إدراج الإعلان الديناميكي" لمحتوى مباشر أو محتوى عند الطلب، وذلك باستخدام حزمة IMA DAI SDK لـ HTML5 مع مشغّل فيديو يعتمد على hls.js لتشغيل المحتوى. للاطّلاع على عملية دمج نموذجية مكتملة أو اتّباعها، مع توفير الدعم لكل من HLS.js وSafari Playback، يمكنك الاطّلاع على مثال على عرض إعلانات ضمن حزمة HLS. للحصول على معلومات حول توافق DASH.js، يُرجى الاطّلاع على مثال على عرض الإعلانات ضمن حزمة DASH. يمكنك تنزيل هذه التطبيقات النموذجية من صفحة إصدار HTML5 DAI على GitHub.

نظرة عامة على ميزة "عرض إعلانات ضمن مجموعة في ميزة إدراج الإعلان الديناميكي"

يتضمّن تنفيذ ميزة "عرض الإعلانات المجمّعة" باستخدام حزمة تطوير البرامج (SDK) الخاصة بميزة "الإعلانات الديناميكية أثناء البث" من "إعلانات الوسائط التفاعلية" مكوّنَين رئيسيَّين، وهما موضّحان في هذا الدليل:

  • ‫PodStreamRequest / PodVodStreamRequest: عنصر يحدّد طلب بث إلى خوادم Google الإعلانية. تحدّد الطلبات رمز الشبكة، ويتطلّب PodStreamRequest أيضًا مفتاح أصل مخصّص ومفتاح واجهة برمجة تطبيقات اختياريًا. يتضمّن كلاهما مَعلمات اختيارية أخرى.

  • StreamManager: عنصر يعالج التواصل بين بث الفيديو و"حزمة تطوير البرامج (SDK) للإعلانات الديناميكية أثناء عرض الفيديو" من "إعلانات الوسائط التفاعلية"، مثل إرسال طلبات ping للتتبّع وإعادة توجيه أحداث البث إلى الناشر.

المتطلبات الأساسية

قبل البدء، يجب توفّر ما يلي:

  • ثلاثة ملفات فارغة:

    • dai.html
    • dai.css
    • dai.js
  • يجب أن يكون لديك Python مثبّت على جهاز الكمبيوتر أو خادم ويب أو بيئة تطوير مستضافة أخرى لاستخدامها في الاختبار.

ضبط بيئة تطوير

بما أنّ حزمة SDK تحمّل التبعيات باستخدام البروتوكول نفسه الذي تستخدمه الصفحة التي يتم تحميل الحزمة منها، عليك استخدام خادم ويب لاختبار تطبيقك. ويمكنك استخدام الخادم المضمّن في Python كطريقة سريعة لبدء خادم تطوير محلي.

  1. باستخدام سطر الأوامر، نفِّذ الأمر التالي من الدليل الذي يحتوي على ملف index.html:

    python -m http.server 8000
  2. في متصفّح ويب، انتقِل إلى 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) الخاصة بميزة "الإعلانات الديناميكية أثناء عرض الفيديو" (DAI)، وذلك قبل إرسال طلب. في هذه الحالة، يتضمّن عنوان URL للبث عنصرًا نائبًا، [[STREAMID]]، يتم استبداله بمعرّف البث قبل تقديم الطلب.

  • NETWORK_CODE: معرِّف الشبكة لحسابك على "إدارة إعلانات Google‏ 360".

  • CUSTOM_ASSET_KEY: يُستخدم فقط في البث المباشر. مفتاح العنصر المخصّص الذي يحدّد حدث "عرض الإعلانات المتسلسلة" في "مدير إعلانات Google". يمكن إنشاء هذا الملف من خلال أداة تعديل ملف البيان أو شريك خارجي يقدّم خدمة Pod Serving.

  • API_KEY: يُستخدم فقط في البث المباشر. مفتاح واجهة برمجة تطبيقات اختياري يمكن أن يكون مطلوبًا لاسترداد معرّف بث من حزمة تطوير البرامج للإعلانات التفاعلية (IMA DAI SDK).

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 باستخدام علامة برمجية في 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، وهو المسؤول عن طلب وإدارة عمليات بث "الإعلانات الديناميكية أثناء عرض الفيديو". يأخذ الدالة الإنشائية عنصر فيديو، ويأخذ المثال الناتج عنصر واجهة مستخدم للإعلان من أجل معالجة التفاعلات مع الإعلان.

بعد ذلك، حدِّد دالة لطلب البث المباشر في 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، وهو المسؤول عن طلب وإدارة عمليات بث "الإعلانات الديناميكية أثناء عرض الفيديو". يأخذ الدالة الإنشائية عنصر فيديو، ويأخذ المثال الناتج عنصر واجهة مستخدم للإعلان من أجل معالجة التفاعلات مع الإعلان.

بعد ذلك، حدِّد دالة لطلب بث 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(). تتعامل هذه الدالة مع تحميل البث والأخطاء، بالإضافة إلى إيقاف عناصر التحكّم في المشغّل أثناء عرض الإعلان، وهو أمر مطلوب من حزمة 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) عند وقوع أحداث الإعلانات. يمكن أن تختلف عملية الاستماع إلى أحداث البيانات الوصفية أثناء عرض الفيديو، وذلك حسب تنسيق البث (البث المباشر وفق بروتوكول HTTP أو البث الديناميكي التكيُّفي عبر HTTP) ونوع البث (بث مباشر أو فيديو عند الطلب) ونوع المشغّل ونوع الخلفية المستخدَمة في "إدراج إعلان ديناميكي". لمزيد من المعلومات، يُرجى الاطّلاع على دليل البيانات الوصفية الموقّتة.

تنسيق البث المباشر وفق بروتوكول 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

بعد الانتهاء بنجاح من طلب الإعلانات وعرضها في بث Pod Serving باستخدام حزمة تطوير البرامج IMA DAI SDK، ننصحك بتنظيف أي موارد بعد اكتمال جلسة Pod Serving. اتّصِل بالرقم StreamManager.destroy() لإيقاف تشغيل البث المباشر، وإيقاف جميع عمليات تتبُّع الإعلانات، وإصدار جميع مواد عرض البث المباشر التي تم تحميلها.

للاطّلاع على المزيد من ميزات حزمة تطوير البرامج المتقدّمة، راجِع الأدلة الأخرى أو الأمثلة على GitHub.