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

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

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

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

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

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

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

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

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

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

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

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

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

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

نظرًا لأن حزمة SDK تحمِّل التبعيات باستخدام البروتوكول نفسه الذي تستخدمه الصفحة من بعد تحميله، ستحتاج إلى استخدام خادم ويب لاختبار التطبيق. خطوة سريعة لبدء خادم تطوير محلي، هي استخدام خادم بايثون المدمج.

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

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

أرسِل البيانات الوصفية لرقم التعريف 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 مع أحداث البث المباشر (تنسيق أحداث البث المباشر باستخدام 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 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.