بدء استخدام حزمة تطوير البرامج لإدراج إعلان ديناميكي لإعلانات الوسائط التفاعلية

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

اختيار حلّ DAI الذي يهمّك

إدراج إعلان ديناميكي في مجموعات الإعلانات

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

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

يتضمّن تنفيذ ميزة عرض مجموعات الإعلانات المتسلسلة باستخدام حزمة تطوير البرامج لميزة DAI في IMA مكوّنَين رئيسيَّين، يتم توضيحهما في هذا الدليل:

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

  • StreamManager: عنصر يعالج التواصل بين مجرى الفيديو وحزمة تطوير البرامج لإدراج إعلان ديناميكي لإعلانات الوسائط التفاعلية (IMA DAI SDK)، مثل تنشيط إشارات التتبّع و forwarded stream events إلى الناشر.

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

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

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

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

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

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

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

    python -m http.server 8000
    
  2. في متصفّح ويب، انتقِل إلى http://localhost:8000/.

    يمكنك أيضًا استخدام أي بيئة تطوير مستضافة أخرى أو خادم ويب آخر، مثل Apache HTTP Server.

إنشاء مشغّل فيديو

أولاً، عدِّل dai.html لإنشاء عنصر فيديو HTML5 وdiv لاستخدامهما في عناصر واجهة مستخدِم الإعلان. أضِف أيضًا العلامات اللازمة لتحميل ملفَي dai.css وdai.js، بالإضافة إلى استيراد مشغّل الفيديو hls.js.

بعد ذلك، عدِّل dai.css لتحديد حجم عناصر الصفحة وموضعها. أخيرًا، في dai.js، حدِّد متغيّرات لتخزين معلومات طلب البث ودالة initPlayer() لتشغيلها عند تحميل الصفحة.

في ما يلي الثوابت لطلبات البث:

  • BACKUP_STREAM: عنوان URL لبث احتياطي يتم تشغيله في حال حدث خطأ فادح في عملية عرض الإعلانات

  • STREAM_URL: تُستخدَم هذه العلامة فقط في أحداث البث المباشر. عنوان URL لبث الفيديو المقدَّم من محرِّر ملف البيان أو شريك خارجي يستخدم ميزة "عرض مجموعة إعلانية" من المفترض أن يُطلب منك إدخال معرّف البث المقدَّم من حزمة تطوير البرامج (SDK) لميزة DAI في IMA قبل إرسال طلب. في هذه الحالة، يتضمّن عنوان URL للبث عنصرًا نائبًا، وهو [[STREAMID]]، ويتم استبداله بمعرّف البث قبل تقديم طلب.

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

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

  • 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="ad-ui"></div>
</body>
</html>

dai.css

#video,
#ad-ui {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0;
}

#ad-ui {
  cursor: pointer;
}

dai.js

var BACKUP_STREAM =
    'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'

// Stream Config.
const STREAM_URL = "https://encodersim.sandbox.google.com/masterPlaylist/...&stream_id=[[STREAMID]]";
const NETWORK_CODE = "51636543";
const CUSTOM_ASSET_KEY = "google-sample";
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، وهو مسؤول عن طلب أحداث "العرض أثناء التشغيل" وإدارتها. يأخذ المُنشئ عنصر فيديو، وتأخذ النسخة الناتجة عنصر واجهة مستخدم للإعلان من أجل معالجة التفاعلات مع الإعلان.

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

تنسيق بث HLS (البث المباشر ومحتوى الفيديو عند الطلب ومشغّل HLS.js)

إذا كنت تستخدِم مشغّل HLS.js، استمع إلى حدث FRAG_PARSING_METADATA في HLS.js للحصول على البيانات الوصفية بتنسيق 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 مع أحداث البث المباشر (تنسيق أحداث البث المباشر باستخدام 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 مع أحداث بث الفيديوهات المسجّلة (تنسيق أحداث بث DASH)

إذا كنت تستخدم مشغّل Shaka لتشغيل تدفق الفيديو عند الطلب، استخدِم السلسلة 'timelineregionenter' للاستماع إلى أحداث metadata. بعد ذلك، استخدِم بيانات رسالة الحدث في طلبك المرسَل إلى 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';
  }
}

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