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

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

اختيار حلّ DAI المطلوب

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

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

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

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

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

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

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

قبل البدء، تحتاج إلى ما يلي:

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

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

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

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

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

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

  • API_KEY: يُستخدَم هذا الخيار لأحداث البث المباشر فقط. مفتاح اختياري لواجهة برمجة التطبيقات يمكن أن يكون مطلوبًا لاسترداد رقم تعريف مصدر البيانات من حزمة تطوير البرامج لإدراج إعلان ديناميكي لإعلانات الوسائط التفاعلية.

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

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

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

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

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

أرسِل البيانات الوصفية لرقم التعريف 3 إلى حزمة تطوير البرامج (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 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)

إذا كنت تستخدم Shka 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';
  }
}

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