راه‌اندازی با درج آگهی پویا در سرویس Pod

پلاتفرم را انتخاب کنید: HTML5 Android iOS tvOS Cast Roku

این راهنما نشان می‌دهد که چگونه بااستفاده از IMA DAI SDK برای HTML5 با پخش‌کننده ویدیویی که برای بازپخش به hls.js متکی است، یک جاری‌سازی «ارائه پاد» DAI را برای محتوای زنده یا VOD پخش کنید. برای مشاهده یا دنبال کردن یک نمونه ادغام تکمیل‌شده، با پشتیبانی از HLS.js و Safari Playback، به نمونه ارائه پاد HLS مراجعه کنید. برای پشتیبانی DASH.js، نمونه ارائه Pod DASH را ببینید. می‌توانید این برنامه‌های نمونه را از صفحه انتشار HTML5 DAI GitHub بارگیری کنید.

نمای کلی ارائه پاد DAI

پیاده‌سازی «ارائه Pod» بااستفاده از «کیت توسعه نرم‌افزار IMA DAI» شامل دو مؤلفه اصلی است که در این راهنما نشان داده شده است:

  • PodStreamRequest / PodVodStreamRequest: شیئی که درخواست جاری‌سازی به سرورهای تبلیغاتی Google را تعریف می‌کند. درخواست‌ها کد شبکه را مشخص می‌کنند و PodStreamRequest همچنین به کلید دارایی سفارشی و کلید میانای برنامه‌سازی کاربردی اختیاری نیاز دارد. هر دو شامل پارامترهای اختیاری دیگر هستند.

  • StreamManager: شیئی که ارتباط بین جاری‌سازی ویدیو و کیت توسعه نرم‌افزار درج آگهی پویا در آگهی‌های رسانه‌ای تعاملی را مدیریت می‌کند، مثلاً پینگ‌های ردیابی را فعال می‌کند و رویدادهای جاری‌سازی را به ناشر بازارسال می‌کند.

پیش‌نیازها

قبل‌از شروع، به موارد زیر نیاز دارید:

  • سه فایل خالی:

    • dai.html
    • dai.css
    • dai.js
  • Python نصب‌شده در رایانه، یا سرور وب یا محیط توسعه میزبانی‌شده دیگر برای استفاده در آزمایش

پیکربندی محیط توسعه نرم‌افزار

ازآنجایی‌که کیت توسعه نرم‌افزار وابستگی‌ها را بااستفاده از همان پروتکل صفحه‌ای که از آن بار شده است بار می‌کند، باید از سرور وب برای آزمایش برنامه‌تان استفاده کنید. راهی سریع برای راه‌اندازی سرور توسعه محلی استفاده از سرور داخلی 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: نشانی وب برای جاری‌سازی پشتیبان برای پخش درصورتی‌که فرایند آگهی‌ها با خطای مهلکی مواجه شود.

  • STREAM_URL: فقط برای جاری‌سازی‌های زنده استفاده می‌شود. نشانی وب جاری‌سازی ویدیو که توسط دستکاری‌کننده مانیفست یا شریک طرف سوم بااستفاده از «ارائه Pod» ارائه شده است. این برنامه باید قبل‌از اینکه درخواست کنید، از شما بخواهد شناسه جاری‌سازی ارائه‌شده توسط IMA DAI SDK را وارد کنید. دراین‌صورت، نشانی وب جاری‌سازی شامل یک جای‌بان، [[STREAMID]]، است که قبل‌از درخواست با شناسه جاری‌سازی جایگزین می‌شود.

  • NETWORK_CODE: کد شبکه برای حساب Ad Manager 360 شما.

  • CUSTOM_ASSET_KEY: فقط برای جاری‌سازی‌های زنده استفاده می‌شود. کلید دارایی سفارشی که رویداد «ارائه پاد» شما را در Ad Manager 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="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 و درخواست جاری‌سازی زنده یا VOD

ارائه پاد جاری‌سازی زنده

برای درخواست مجموعه‌ای از آگهی‌ها، یک ima.dai.api.StreamManager ایجاد کنید که مسئول درخواست و مدیریت جریان‌های DAI است. سازنده یک عنصر ویدیو را می‌گیرد و نمونه حاصل یک عنصر میانای کاربر آگهی را برای مدیریت تعاملات آگهی می‌گیرد.

سپس، تابعی را برای درخواست جاری‌سازی زنده «ارائه Pod» تعریف کنید. این تابع ابتدا یک PodStreamRequest ایجاد می‌کند، آن را با پارامترهای streamRequest ارائه‌شده در مرحله ۲ پیکربندی می‌کند، و سپس 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 است. سازنده یک عنصر ویدیو را می‌گیرد و نمونه حاصل یک عنصر میانای کاربر آگهی را برای مدیریت تعاملات آگهی می‌گیرد.

سپس، تابعی را برای درخواست جاری‌سازی ویدیو به‌درخواست Pod Serving تعریف کنید. این تابع ابتدا یک PodVodStreamRequest ایجاد می‌کند، آن را با پارامترهای streamRequest ارائه‌شده در مرحله ۲ پیکربندی می‌کند، و سپس 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() مدیریت می‌کند. این تابع بارگیری جاری‌سازی و خطاها را مدیریت می‌کند و همچنین کنترل‌های پخش‌کننده را درحین پخش آگهی غیرفعال می‌کند که این کار برای کیت توسعه نرم‌افزار الزامی است. وقتی جاری‌سازی بار می‌شود، پخش‌کننده ویدیو بااستفاده از تابع 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» نیاز به فراخوانی StreamManager.loadStreamMetadata() در پاسخ به رویداد STREAM_INITIALIZED دارد. همچنین باید نشانی وب جاری‌سازی را از شریک فناوری ویدیویی (VTP) خود درخواست کنید. وقتی فراخوانی loadStreamMetadata() موفقیت‌آمیز باشد، رویداد LOADED را راه‌اندازی می‌کند، که در آن باید تابع loadStream() را با نشانی وب جاری‌سازی‌تان فراخوانی کنید تا جاری‌سازی بار شود و پخش شود.

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);
}

مدیریت فراداده جاری‌سازی

در این مرحله، شنوندگان رویداد را برای فراداده پیاده‌سازی می‌کنید تا هنگام وقوع رویدادهای آگهی به کیت توسعه نرم‌افزار اطلاع دهند. گوش دادن به رویدادهای فراداده درون جاری‌سازی می‌تواند متفاوت باشد، بسته به قالب جاری‌سازی (HLS یا DASH)، نوع جاری‌سازی (جاری‌سازی زنده یا ویدیو به‌درخواست)، نوع پخش‌کننده شما، و نوع پسوند DAI که استفاده می‌شود. برای اطلاعات بیشتر، راهنمای فراداده زمان‌بندی‌شده ما را ببینید.

قالب جاری‌سازی HLS (جاری‌سازی‌های زنده و ویدیو به‌درخواست، پخش‌کننده HLS.js)

اگر از پخش‌کننده HLS.js استفاده می‌کنید، به رویداد HLS.js FRAG_PARSING_METADATA گوش دهید تا فراداده ID3 را دریافت کنید و آن را با 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، نوع جاری‌سازی زنده و VOD)

اگر از پخش‌کننده DASH.js استفاده می‌کنید، باید از رشته‌های مختلفی برای گوش دادن به فراداده ID3 برای جاری‌سازی‌های زنده یا ویدیو به‌درخواست استفاده کنید:

  • جاری‌سازی‌های زنده: 'https://developer.apple.com/streaming/emsg-id3'
  • جاری‌سازی‌های ویدیو به‌درخواست: 'urn:google:dai:2018'

فراداده ID3 را با 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)

اگر از Shaka player برای بازپخش جاری‌سازی VOD استفاده می‌کنید، از رشته '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 stream با IMA DAI SDK با موفقیت به پایان رساندید، پیشنهاد می‌کنیم پس‌از تکمیل جلسه Pod Serving، منابع را پاک‌سازی کنید. برای توقف بازپخش جاری‌سازی، توقف همه ردگیری‌های آگهی، و واگذاری همه دارایی‌های جاری‌سازی بارشده، StreamManager.destroy() را فراخوانی کنید.

برای آشنایی با ویژگی‌های پیشرفته‌تر SDK، به راهنماهای دیگر یا نمونه‌های موجود در GitHub مراجعه کنید.