با IMA DAI SDK شروع کنید

IMA SDK ادغام تبلیغات چندرسانه ای را در وب سایت ها و برنامه های شما آسان می کند. IMA SDK می‌تواند از هر سرور تبلیغاتی سازگار با VAST آگهی درخواست کند و پخش آگهی را در برنامه‌های شما مدیریت کند. با IMA DAI SDK، برنامه‌ها درخواست پخش جریانی برای آگهی و ویدیوی محتوا را ارائه می‌کنند - اعم از VOD یا محتوای زنده. سپس SDK یک جریان ویدیوی ترکیبی را برمی‌گرداند، به طوری که نیازی به مدیریت جابجایی بین آگهی و ویدیوی محتوا در برنامه خود ندارید.

راه حل DAI مورد علاقه خود را انتخاب کنید

خدمات کامل DAI

این راهنما نحوه ادغام IMA DAI SDK را در یک برنامه پخش کننده ویدیوی ساده نشان می دهد. اگر می‌خواهید نمونه یکپارچه‌سازی کامل شده را مشاهده یا دنبال کنید، نمونه اولیه را از GitHub دانلود کنید.

نمای کلی IMA DAI

پیاده سازی IMA DAI شامل دو جزء اصلی SDK است که در این راهنما نشان داده شده است:

  • StreamRequest : یک شی که یک درخواست جریان را تعریف می کند. درخواست‌های جریان می‌تواند برای ویدیوی درخواستی یا پخش مستقیم باشد. درخواست ها یک شناسه محتوا و همچنین یک کلید API یا نشانه احراز هویت و سایر پارامترها را مشخص می کنند.
  • StreamManager : شیئی که جریانهای درج آگهی پویا و تعاملات با باطن DAI را مدیریت می کند. مدیر جریان همچنین پینگ‌های ردیابی را مدیریت می‌کند و جریان‌ها و رویدادهای تبلیغاتی را به ناشر ارسال می‌کند.

پیش نیازها

  • صفحه سازگاری ما را بخوانید تا مطمئن شوید مورد استفاده مورد نظر شما پشتیبانی می شود.
  • کد پخش کننده نمونه Roku ما را دانلود کنید
  • کد پخش کننده نمونه را در دستگاه Roku مستقر کنید تا تأیید کنید که تنظیمات توسعه شما کار می کند.

ویدیوی خود را پخش کنید

پخش کننده ویدیوی نمونه ارائه شده یک ویدیوی محتوایی را خارج از جعبه پخش می کند. پخش کننده نمونه را در پخش کننده Roku خود مستقر کنید تا مطمئن شوید که محیط توسعه شما به درستی تنظیم شده است.

پخش کننده ویدیوی خود را به یک پخش کننده جریانی IMA DAI تبدیل کنید

این مراحل را برای پیاده سازی پخش کننده استریم دنبال کنید.

Sdk.xml ایجاد کنید

یک فایل جدید به پروژه خود در کنار MainScene.xml به نام Sdk.xml اضافه کنید و boilerplate زیر را اضافه کنید:

Sdk.xml

<?xml version = "1.0" encoding = "utf-8" ?>

<component name = "imasdk" extends = "Task">
<interface>
</interface>
<script type = "text/brightscript">
<![CDATA[
  ' Your code goes here.
]]>
</script>
</component>

شما باید هر دوی این فایل ها را در این راهنما ویرایش کنید.

چارچوب تبلیغاتی Roku را بارگیری کنید

IMA DAI SDK به چارچوب تبلیغات Roku بستگی دارد. برای بارگیری چارچوب، موارد زیر را به manifest و Sdk.xml اضافه کنید:

آشکار

bs_libs_required=roku_ads_lib,googleima3

Sdk.xml

Library "Roku_Ads.brs"
Library "IMA3.brs"

IMA DAI SDK را بارگیری کنید

اولین قدم برای بارگیری جریان درج آگهی پویا IMA، بارگیری و مقداردهی اولیه IMA DAI SDK است. موارد زیر اسکریپت IMA DAI SDK را بارگیری می کند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
</interface>
...
Sub init()
  m.top.functionName = "runThread"
End Sub

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
End Sub

Sub loadSdk()
    If m.sdk = invalid
      m.sdk = New_IMASDK()
    End If
    m.top.sdkLoaded = true
End Sub

اکنون این کار را در MainScene.xml شروع کنید و تماس را حذف کنید تا جریان محتوا بارگیری شود.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  m.sdkTask.control = "RUN"
end function

Sub onSdkLoaded(message as Object)
  print "----- onSdkLoaded --- control ";message
End Sub

Sub onSdkLoadedError(message as Object)
  print "----- errors in the sdk loading process --- ";message
End Sub

یک پخش کننده جریان IMA ایجاد کنید

در مرحله بعد، باید از roVideoScreen موجود خود برای ایجاد یک پخش کننده جریان IMA استفاده کنید. این پخش کننده جریانی سه روش پاسخ به تماس را پیاده سازی می کند: loadUrl ، adBreakStarted ، و adBreakEnded . همچنین، هنگام بارگیری جریان، پخش ترفند را غیرفعال کنید. این کار باعث می‌شود که کاربران نتوانند در همان لحظه که شروع می‌شود، قبل از فعال شدن رویداد شروع شکستن آگهی، از پرش پرش کنند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
</interface>
...
Sub setupVideoPlayer()
  sdk = m.sdk
  m.player = sdk.createPlayer()
  m.player.top = m.top
  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function
  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function
  m.player.adBreakEnded = Function(adBreakInfo as Object)
    print "---- Ad Break Ended ---- "
    m.top.adPlaying = False
    m.top.video.enableTrickPlay = true
  End Function
End Sub

یک درخواست جریان ایجاد و اجرا کنید

اکنون که یک پخش کننده پخش جریانی دارید، می توانید یک درخواست استریم ایجاد و اجرا کنید. این مثال دارای داده‌هایی برای یک جریان زنده و یک جریان VOD است. از جریان VOD استفاده می‌کند، اما می‌توانید با تغییر selectedStream از m.testVodStream به m.testLiveStream به جای آن از پخش زنده استفاده کنید.

برای اینکه بتوانید از AdUI مانند نمادهای adChoices پشتیبانی کنید، باید به عنوان بخشی از درخواست خود، یک مرجع به گره حاوی ویدیوی محتوای خود ارسال کنید.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  m.testLiveStream = {
    title: "Livestream",
    assetKey: "sN_IYUG8STe1ZzhIIE_ksA",
    apiKey: "",
    type: "live"
  }
  m.testVodStream = {
    title: "VOD stream"
    contentSourceId: "2548831",
    videoId: "tears-of-steel",
    apiKey: "",
    type: "vod"
  }
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
  <field id="streamData" type="assocarray" />
  <field id="streamManagerReady" type="Boolean" />
</interface>
...
Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
End Sub

Sub loadStream()
  sdk = m.sdk
  sdk.initSdk()
  setupVideoPlayer()

  request = {}
  streamData = m.top.streamData
  if streamData.type = "live"
    request = sdk.CreateLiveStreamRequest(streamData.assetKey, streamData.apiKey)
  else if streamData.type = "vod"
    request = sdk.CreateVodStreamRequest(streamData.contentSourceId, streamData.videoId, streamData.apiKey)
  else
    request = sdk.CreateStreamRequest()
  end if

  request.player = m.player
  request.videoObject = m.top.video
  ' Required to support UI elements for 'Why This Ad?' and skippability
  request.adUiNode = m.top.video

  requestResult = sdk.requestStream(request)
  If requestResult &lt;&gt; Invalid
    print "Error requesting stream ";requestResult
  Else
    m.streamManager = Invalid
    While m.streamManager = Invalid
      sleep(50)
      m.streamManager = sdk.getStreamManager()
    End While
    If m.streamManager = Invalid or m.streamManager["type"] &lt;&gt; Invalid or m.streamManager["type"] = "error"
      errors = CreateObject("roArray", 1, True)
      print "error ";m.streamManager["info"]
      errors.push(m.streamManager["info"])
      m.top.errors = errors
    Else
      m.top.streamManagerReady = True
      addCallbacks()
      m.streamManager.start()
    End If
  End If
End Sub

شنوندگان رویداد را اضافه کنید و جریان را شروع کنید

پس از درخواست پخش خود، تنها چند کار باقی مانده است که باید انجام دهید: اضافه کردن شنوندگان رویداد برای ردیابی پیشرفت تبلیغات، شروع جریان خود و ارسال پیام‌های Roku به SDK.

MainScene.xml

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.observeField("urlData", "urlLoadRequested")
  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sub urlLoadRequested(message as Object)
  print "Url Load Requested ";message
  data = message.getData()

  playStream(data.manifest)
End Sub

Sub playStream(url as Object)
  vidContent = createObject("RoSGNode", "ContentNode")
  vidContent.url = url
  vidContent.title = m.videoTitle
  vidContent.streamformat = "hls"
  m.video.content = vidContent
  m.video.setFocus(true)
  m.video.visible = true
  m.video.control = "play"
  m.video.EnableCookies()
End Sub

Sdk.xml

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
  If m.top.streamManagerReady
    runLoop()
  End If
End Sub

Sub runLoop()
  m.top.video.timedMetaDataSelectionKeys = ["*"]

  m.port = CreateObject("roMessagePort")

  ' Listen to all fields.

  ' IMPORTANT: Failure to listen to the position and timedmetadata fields
  ' could result in ad impressions not being reported.
  fields = m.top.video.getFields()
  for each field in fields
    m.top.video.observeField(field, m.port)
  end for

  while True
    msg = wait(1000, m.port)
    if m.top.video = invalid
      print "exiting"
      exit while
    end if

    m.streamManager.onMessage(msg)
    currentTime = m.top.video.position
    If currentTime > 3 And not m.top.adPlaying
       m.top.video.enableTrickPlay = true
    End If
  end while
End Sub

Function addCallbacks() as Void
  m.streamManager.addEventListener(m.sdk.AdEvent.ERROR, errorCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.START, startCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.FIRST_QUARTILE, firstQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.MIDPOINT, midpointCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.THIRD_QUARTILE, thirdQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.COMPLETE, completeCallback)
End Function

Function startCallback(ad as Object) as Void
  print "Callback from SDK -- Start called - "
End Function

Function firstQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- First quartile called - "
End Function

Function midpointCallback(ad as Object) as Void
  print "Callback from SDK -- Midpoint called - "
End Function

Function thirdQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- Third quartile called - "
End Function

Function completeCallback(ad as Object) as Void
  print "Callback from SDK -- Complete called - "
End Function

Function errorCallback(error as Object) as Void
  print "Callback from SDK -- Error called - "; error
  m.errorState = True
End Function

افزودن پشتیبانی برای تبلیغات قابل رد شدن (اختیاری)

In order to support skippable ads, you need to add a seek method to the IMA DAI SDK's player object that programmatically seeks the video to the specified location, in floating-point seconds.

برای پشتیبانی از تبلیغات قابل پرش، باید مطمئن شوید که adUiNode را در درخواست خود تنظیم کرده اید.

Sdk.xml

  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function

  m.player.seek = Function(timeSeconds as Float)
     print "---- SDK requested seek to ----" ; timeSeconds
     m.top.video.seekMode = "accurate"
     m.top.video.seek = timeSeconds
  End Function

  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function
،

IMA SDK ادغام تبلیغات چندرسانه ای را در وب سایت ها و برنامه های شما آسان می کند. IMA SDK می‌تواند از هر سرور تبلیغاتی سازگار با VAST آگهی درخواست کند و پخش آگهی را در برنامه‌های شما مدیریت کند. با IMA DAI SDK، برنامه‌ها درخواست پخش جریانی برای آگهی و ویدیوی محتوا را ارائه می‌کنند - اعم از VOD یا محتوای زنده. سپس SDK یک جریان ویدیوی ترکیبی را برمی‌گرداند، به طوری که نیازی به مدیریت جابجایی بین آگهی و ویدیوی محتوا در برنامه خود ندارید.

راه حل DAI مورد علاقه خود را انتخاب کنید

خدمات کامل DAI

این راهنما نحوه ادغام IMA DAI SDK را در یک برنامه پخش کننده ویدیوی ساده نشان می دهد. اگر می‌خواهید نمونه یکپارچه‌سازی کامل شده را مشاهده یا دنبال کنید، نمونه اولیه را از GitHub دانلود کنید.

نمای کلی IMA DAI

پیاده سازی IMA DAI شامل دو جزء اصلی SDK است که در این راهنما نشان داده شده است:

  • StreamRequest : یک شی که یک درخواست جریان را تعریف می کند. درخواست‌های جریان می‌تواند برای ویدیوی درخواستی یا پخش مستقیم باشد. درخواست ها یک شناسه محتوا و همچنین یک کلید API یا نشانه احراز هویت و سایر پارامترها را مشخص می کنند.
  • StreamManager : شیئی که جریانهای درج آگهی پویا و تعاملات با باطن DAI را مدیریت می کند. مدیر جریان همچنین پینگ‌های ردیابی را مدیریت می‌کند و جریان‌ها و رویدادهای تبلیغاتی را به ناشر ارسال می‌کند.

پیش نیازها

  • صفحه سازگاری ما را بخوانید تا مطمئن شوید مورد استفاده مورد نظر شما پشتیبانی می شود.
  • کد پخش کننده نمونه Roku ما را دانلود کنید
  • کد پخش کننده نمونه را در دستگاه Roku مستقر کنید تا تأیید کنید که تنظیمات توسعه شما کار می کند.

ویدیوی خود را پخش کنید

پخش کننده ویدیوی نمونه ارائه شده یک ویدیوی محتوایی را خارج از جعبه پخش می کند. پخش کننده نمونه را در پخش کننده Roku خود مستقر کنید تا مطمئن شوید که محیط توسعه شما به درستی تنظیم شده است.

پخش کننده ویدیوی خود را به یک پخش کننده جریانی IMA DAI تبدیل کنید

این مراحل را برای پیاده سازی پخش کننده استریم دنبال کنید.

Sdk.xml ایجاد کنید

یک فایل جدید به پروژه خود در کنار MainScene.xml به نام Sdk.xml اضافه کنید و boilerplate زیر را اضافه کنید:

Sdk.xml

<?xml version = "1.0" encoding = "utf-8" ?>

<component name = "imasdk" extends = "Task">
<interface>
</interface>
<script type = "text/brightscript">
<![CDATA[
  ' Your code goes here.
]]>
</script>
</component>

شما باید هر دوی این فایل ها را در این راهنما ویرایش کنید.

چارچوب تبلیغاتی Roku را بارگیری کنید

IMA DAI SDK به چارچوب تبلیغات Roku بستگی دارد. برای بارگیری چارچوب، موارد زیر را به manifest و Sdk.xml اضافه کنید:

آشکار

bs_libs_required=roku_ads_lib,googleima3

Sdk.xml

Library "Roku_Ads.brs"
Library "IMA3.brs"

IMA DAI SDK را بارگیری کنید

اولین قدم برای بارگیری جریان درج آگهی پویا IMA، بارگیری و مقداردهی اولیه IMA DAI SDK است. موارد زیر اسکریپت IMA DAI SDK را بارگیری می کند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
</interface>
...
Sub init()
  m.top.functionName = "runThread"
End Sub

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
End Sub

Sub loadSdk()
    If m.sdk = invalid
      m.sdk = New_IMASDK()
    End If
    m.top.sdkLoaded = true
End Sub

اکنون این کار را در MainScene.xml شروع کنید و تماس را حذف کنید تا جریان محتوا بارگیری شود.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  m.sdkTask.control = "RUN"
end function

Sub onSdkLoaded(message as Object)
  print "----- onSdkLoaded --- control ";message
End Sub

Sub onSdkLoadedError(message as Object)
  print "----- errors in the sdk loading process --- ";message
End Sub

یک پخش کننده جریان IMA ایجاد کنید

در مرحله بعد، باید از roVideoScreen موجود خود برای ایجاد یک پخش کننده جریان IMA استفاده کنید. این پخش کننده جریانی سه روش پاسخ به تماس را پیاده سازی می کند: loadUrl ، adBreakStarted ، و adBreakEnded . همچنین، هنگام بارگیری جریان، پخش ترفند را غیرفعال کنید. این کار باعث می‌شود که کاربران نتوانند در همان لحظه که شروع می‌شود، قبل از فعال شدن رویداد شروع شکستن آگهی، از پرش پرش کنند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
</interface>
...
Sub setupVideoPlayer()
  sdk = m.sdk
  m.player = sdk.createPlayer()
  m.player.top = m.top
  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function
  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function
  m.player.adBreakEnded = Function(adBreakInfo as Object)
    print "---- Ad Break Ended ---- "
    m.top.adPlaying = False
    m.top.video.enableTrickPlay = true
  End Function
End Sub

یک درخواست جریان ایجاد و اجرا کنید

اکنون که یک پخش کننده پخش جریانی دارید، می توانید یک درخواست استریم ایجاد و اجرا کنید. این مثال دارای داده‌هایی برای یک جریان زنده و یک جریان VOD است. از جریان VOD استفاده می‌کند، اما می‌توانید با تغییر selectedStream از m.testVodStream به m.testLiveStream به جای آن از پخش زنده استفاده کنید.

برای اینکه بتوانید از AdUI مانند نمادهای adChoices پشتیبانی کنید، باید به عنوان بخشی از درخواست خود، یک مرجع به گره حاوی ویدیوی محتوای خود ارسال کنید.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  m.testLiveStream = {
    title: "Livestream",
    assetKey: "sN_IYUG8STe1ZzhIIE_ksA",
    apiKey: "",
    type: "live"
  }
  m.testVodStream = {
    title: "VOD stream"
    contentSourceId: "2548831",
    videoId: "tears-of-steel",
    apiKey: "",
    type: "vod"
  }
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
  <field id="streamData" type="assocarray" />
  <field id="streamManagerReady" type="Boolean" />
</interface>
...
Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
End Sub

Sub loadStream()
  sdk = m.sdk
  sdk.initSdk()
  setupVideoPlayer()

  request = {}
  streamData = m.top.streamData
  if streamData.type = "live"
    request = sdk.CreateLiveStreamRequest(streamData.assetKey, streamData.apiKey)
  else if streamData.type = "vod"
    request = sdk.CreateVodStreamRequest(streamData.contentSourceId, streamData.videoId, streamData.apiKey)
  else
    request = sdk.CreateStreamRequest()
  end if

  request.player = m.player
  request.videoObject = m.top.video
  ' Required to support UI elements for 'Why This Ad?' and skippability
  request.adUiNode = m.top.video

  requestResult = sdk.requestStream(request)
  If requestResult &lt;&gt; Invalid
    print "Error requesting stream ";requestResult
  Else
    m.streamManager = Invalid
    While m.streamManager = Invalid
      sleep(50)
      m.streamManager = sdk.getStreamManager()
    End While
    If m.streamManager = Invalid or m.streamManager["type"] &lt;&gt; Invalid or m.streamManager["type"] = "error"
      errors = CreateObject("roArray", 1, True)
      print "error ";m.streamManager["info"]
      errors.push(m.streamManager["info"])
      m.top.errors = errors
    Else
      m.top.streamManagerReady = True
      addCallbacks()
      m.streamManager.start()
    End If
  End If
End Sub

شنوندگان رویداد را اضافه کنید و جریان را شروع کنید

پس از درخواست پخش خود، تنها چند کار باقی مانده است که باید انجام دهید: اضافه کردن شنوندگان رویداد برای ردیابی پیشرفت تبلیغات، شروع جریان خود و ارسال پیام‌های Roku به SDK.

MainScene.xml

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.observeField("urlData", "urlLoadRequested")
  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sub urlLoadRequested(message as Object)
  print "Url Load Requested ";message
  data = message.getData()

  playStream(data.manifest)
End Sub

Sub playStream(url as Object)
  vidContent = createObject("RoSGNode", "ContentNode")
  vidContent.url = url
  vidContent.title = m.videoTitle
  vidContent.streamformat = "hls"
  m.video.content = vidContent
  m.video.setFocus(true)
  m.video.visible = true
  m.video.control = "play"
  m.video.EnableCookies()
End Sub

Sdk.xml

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
  If m.top.streamManagerReady
    runLoop()
  End If
End Sub

Sub runLoop()
  m.top.video.timedMetaDataSelectionKeys = ["*"]

  m.port = CreateObject("roMessagePort")

  ' Listen to all fields.

  ' IMPORTANT: Failure to listen to the position and timedmetadata fields
  ' could result in ad impressions not being reported.
  fields = m.top.video.getFields()
  for each field in fields
    m.top.video.observeField(field, m.port)
  end for

  while True
    msg = wait(1000, m.port)
    if m.top.video = invalid
      print "exiting"
      exit while
    end if

    m.streamManager.onMessage(msg)
    currentTime = m.top.video.position
    If currentTime > 3 And not m.top.adPlaying
       m.top.video.enableTrickPlay = true
    End If
  end while
End Sub

Function addCallbacks() as Void
  m.streamManager.addEventListener(m.sdk.AdEvent.ERROR, errorCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.START, startCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.FIRST_QUARTILE, firstQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.MIDPOINT, midpointCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.THIRD_QUARTILE, thirdQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.COMPLETE, completeCallback)
End Function

Function startCallback(ad as Object) as Void
  print "Callback from SDK -- Start called - "
End Function

Function firstQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- First quartile called - "
End Function

Function midpointCallback(ad as Object) as Void
  print "Callback from SDK -- Midpoint called - "
End Function

Function thirdQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- Third quartile called - "
End Function

Function completeCallback(ad as Object) as Void
  print "Callback from SDK -- Complete called - "
End Function

Function errorCallback(error as Object) as Void
  print "Callback from SDK -- Error called - "; error
  m.errorState = True
End Function

افزودن پشتیبانی برای تبلیغات قابل رد شدن (اختیاری)

به منظور پشتیبانی از تبلیغات قابل پرش، باید یک روش seek را به شی پخش کننده IMA DAI SDK اضافه کنید که به صورت برنامه‌ریزی ویدیو را در مکان مشخص شده در ثانیه ممیز شناور جستجو کند.

برای پشتیبانی از تبلیغات قابل پرش، باید مطمئن شوید که adUiNode را در درخواست خود تنظیم کرده اید.

Sdk.xml

  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function

  m.player.seek = Function(timeSeconds as Float)
     print "---- SDK requested seek to ----" ; timeSeconds
     m.top.video.seekMode = "accurate"
     m.top.video.seek = timeSeconds
  End Function

  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function
،

IMA SDK ادغام تبلیغات چندرسانه ای را در وب سایت ها و برنامه های شما آسان می کند. IMA SDK می‌تواند از هر سرور تبلیغاتی سازگار با VAST آگهی درخواست کند و پخش آگهی را در برنامه‌های شما مدیریت کند. با IMA DAI SDK، برنامه‌ها درخواست پخش جریانی برای آگهی و ویدیوی محتوا را ارائه می‌کنند - اعم از VOD یا محتوای زنده. سپس SDK یک جریان ویدیوی ترکیبی را برمی‌گرداند، به طوری که نیازی به مدیریت جابجایی بین آگهی و ویدیوی محتوا در برنامه خود ندارید.

راه حل DAI مورد علاقه خود را انتخاب کنید

خدمات کامل DAI

این راهنما نحوه ادغام IMA DAI SDK را در یک برنامه پخش کننده ویدیوی ساده نشان می دهد. اگر می‌خواهید نمونه یکپارچه‌سازی کامل شده را مشاهده یا دنبال کنید، نمونه اولیه را از GitHub دانلود کنید.

نمای کلی IMA DAI

پیاده سازی IMA DAI شامل دو جزء اصلی SDK است که در این راهنما نشان داده شده است:

  • StreamRequest : یک شی که یک درخواست جریان را تعریف می کند. درخواست‌های جریان می‌تواند برای ویدیوی درخواستی یا پخش مستقیم باشد. درخواست ها یک شناسه محتوا و همچنین یک کلید API یا نشانه احراز هویت و سایر پارامترها را مشخص می کنند.
  • StreamManager : شیئی که جریانهای درج آگهی پویا و تعاملات با باطن DAI را مدیریت می کند. مدیر جریان همچنین پینگ‌های ردیابی را مدیریت می‌کند و جریان‌ها و رویدادهای تبلیغاتی را به ناشر ارسال می‌کند.

پیش نیازها

  • صفحه سازگاری ما را بخوانید تا مطمئن شوید مورد استفاده مورد نظر شما پشتیبانی می شود.
  • کد پخش کننده نمونه Roku ما را دانلود کنید
  • کد پخش کننده نمونه را در دستگاه Roku مستقر کنید تا تأیید کنید که تنظیمات توسعه شما کار می کند.

ویدیوی خود را پخش کنید

پخش کننده ویدیوی نمونه ارائه شده یک ویدیوی محتوایی را خارج از جعبه پخش می کند. پخش کننده نمونه را در پخش کننده Roku خود مستقر کنید تا مطمئن شوید که محیط توسعه شما به درستی تنظیم شده است.

پخش کننده ویدیوی خود را به یک پخش کننده جریانی IMA DAI تبدیل کنید

این مراحل را برای پیاده سازی پخش کننده استریم دنبال کنید.

Sdk.xml ایجاد کنید

یک فایل جدید به پروژه خود در کنار MainScene.xml به نام Sdk.xml اضافه کنید و boilerplate زیر را اضافه کنید:

Sdk.xml

<?xml version = "1.0" encoding = "utf-8" ?>

<component name = "imasdk" extends = "Task">
<interface>
</interface>
<script type = "text/brightscript">
<![CDATA[
  ' Your code goes here.
]]>
</script>
</component>

شما باید هر دوی این فایل ها را در این راهنما ویرایش کنید.

چارچوب تبلیغاتی Roku را بارگیری کنید

IMA DAI SDK به چارچوب تبلیغات Roku بستگی دارد. برای بارگیری چارچوب، موارد زیر را به manifest و Sdk.xml اضافه کنید:

آشکار

bs_libs_required=roku_ads_lib,googleima3

Sdk.xml

Library "Roku_Ads.brs"
Library "IMA3.brs"

IMA DAI SDK را بارگیری کنید

اولین قدم برای بارگیری جریان درج آگهی پویا IMA، بارگیری و مقداردهی اولیه IMA DAI SDK است. موارد زیر اسکریپت IMA DAI SDK را بارگیری می کند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
</interface>
...
Sub init()
  m.top.functionName = "runThread"
End Sub

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
End Sub

Sub loadSdk()
    If m.sdk = invalid
      m.sdk = New_IMASDK()
    End If
    m.top.sdkLoaded = true
End Sub

اکنون این کار را در MainScene.xml شروع کنید و تماس را حذف کنید تا جریان محتوا بارگیری شود.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  m.sdkTask.control = "RUN"
end function

Sub onSdkLoaded(message as Object)
  print "----- onSdkLoaded --- control ";message
End Sub

Sub onSdkLoadedError(message as Object)
  print "----- errors in the sdk loading process --- ";message
End Sub

یک پخش کننده جریان IMA ایجاد کنید

در مرحله بعد، باید از roVideoScreen موجود خود برای ایجاد یک پخش کننده جریان IMA استفاده کنید. این پخش کننده جریانی سه روش پاسخ به تماس را پیاده سازی می کند: loadUrl ، adBreakStarted ، و adBreakEnded . همچنین، هنگام بارگیری جریان، پخش ترفند را غیرفعال کنید. این کار باعث می‌شود که کاربران نتوانند در همان لحظه که شروع می‌شود، قبل از فعال شدن رویداد شروع شکستن آگهی، از پرش پرش کنند.

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
</interface>
...
Sub setupVideoPlayer()
  sdk = m.sdk
  m.player = sdk.createPlayer()
  m.player.top = m.top
  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function
  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function
  m.player.adBreakEnded = Function(adBreakInfo as Object)
    print "---- Ad Break Ended ---- "
    m.top.adPlaying = False
    m.top.video.enableTrickPlay = true
  End Function
End Sub

یک درخواست جریان ایجاد و اجرا کنید

اکنون که یک پخش کننده پخش جریانی دارید، می توانید یک درخواست استریم ایجاد و اجرا کنید. این مثال دارای داده‌هایی برای یک جریان زنده و یک جریان VOD است. از جریان VOD استفاده می‌کند، اما می‌توانید با تغییر selectedStream از m.testVodStream به m.testLiveStream به جای آن از پخش زنده استفاده کنید.

برای اینکه بتوانید از AdUI مانند نمادهای adChoices پشتیبانی کنید، باید به عنوان بخشی از درخواست خود، یک مرجع به گره حاوی ویدیوی محتوای خود ارسال کنید.

MainScene.xml

function init()
  m.video = m.top.findNode("myVideo")
  m.video.notificationinterval = 1
  m.testLiveStream = {
    title: "Livestream",
    assetKey: "sN_IYUG8STe1ZzhIIE_ksA",
    apiKey: "",
    type: "live"
  }
  m.testVodStream = {
    title: "VOD stream"
    contentSourceId: "2548831",
    videoId: "tears-of-steel",
    apiKey: "",
    type: "vod"
  }
  loadImaSdk()
end function

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sdk.xml

<interface>
  <field id="sdkLoaded" type="Boolean" />
  <field id="errors" type="stringarray" />
  <field id="urlData" type="assocarray" />
  <field id="adPlaying" type="Boolean" />
  <field id="video" type="Node" />
  <field id="streamData" type="assocarray" />
  <field id="streamManagerReady" type="Boolean" />
</interface>
...
Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
End Sub

Sub loadStream()
  sdk = m.sdk
  sdk.initSdk()
  setupVideoPlayer()

  request = {}
  streamData = m.top.streamData
  if streamData.type = "live"
    request = sdk.CreateLiveStreamRequest(streamData.assetKey, streamData.apiKey)
  else if streamData.type = "vod"
    request = sdk.CreateVodStreamRequest(streamData.contentSourceId, streamData.videoId, streamData.apiKey)
  else
    request = sdk.CreateStreamRequest()
  end if

  request.player = m.player
  request.videoObject = m.top.video
  ' Required to support UI elements for 'Why This Ad?' and skippability
  request.adUiNode = m.top.video

  requestResult = sdk.requestStream(request)
  If requestResult &lt;&gt; Invalid
    print "Error requesting stream ";requestResult
  Else
    m.streamManager = Invalid
    While m.streamManager = Invalid
      sleep(50)
      m.streamManager = sdk.getStreamManager()
    End While
    If m.streamManager = Invalid or m.streamManager["type"] &lt;&gt; Invalid or m.streamManager["type"] = "error"
      errors = CreateObject("roArray", 1, True)
      print "error ";m.streamManager["info"]
      errors.push(m.streamManager["info"])
      m.top.errors = errors
    Else
      m.top.streamManagerReady = True
      addCallbacks()
      m.streamManager.start()
    End If
  End If
End Sub

شنوندگان رویداد را اضافه کنید و جریان را شروع کنید

پس از درخواست پخش خود، تنها چند کار باقی مانده است که باید انجام دهید: اضافه کردن شنوندگان رویداد برای ردیابی پیشرفت تبلیغات، شروع جریان خود و ارسال پیام‌های Roku به SDK.

MainScene.xml

function loadImaSdk() as void
  m.sdkTask = createObject("roSGNode", "imasdk")
  m.sdkTask.observeField("sdkLoaded", "onSdkLoaded")
  m.sdkTask.observeField("errors", "onSdkLoadedError")

  selectedStream = m.testVodStream
  m.videoTitle = selectedStream.title
  m.sdkTask.streamData = selectedStream

  m.sdkTask.observeField("urlData", "urlLoadRequested")
  m.sdkTask.video = m.video
  m.sdkTask.control = "RUN"
end function

Sub urlLoadRequested(message as Object)
  print "Url Load Requested ";message
  data = message.getData()

  playStream(data.manifest)
End Sub

Sub playStream(url as Object)
  vidContent = createObject("RoSGNode", "ContentNode")
  vidContent.url = url
  vidContent.title = m.videoTitle
  vidContent.streamformat = "hls"
  m.video.content = vidContent
  m.video.setFocus(true)
  m.video.visible = true
  m.video.control = "play"
  m.video.EnableCookies()
End Sub

Sdk.xml

Sub runThread()
  if not m.top.sdkLoaded
    loadSdk()
  End If
  if not m.top.streamManagerReady
    loadStream()
  End If
  If m.top.streamManagerReady
    runLoop()
  End If
End Sub

Sub runLoop()
  m.top.video.timedMetaDataSelectionKeys = ["*"]

  m.port = CreateObject("roMessagePort")

  ' Listen to all fields.

  ' IMPORTANT: Failure to listen to the position and timedmetadata fields
  ' could result in ad impressions not being reported.
  fields = m.top.video.getFields()
  for each field in fields
    m.top.video.observeField(field, m.port)
  end for

  while True
    msg = wait(1000, m.port)
    if m.top.video = invalid
      print "exiting"
      exit while
    end if

    m.streamManager.onMessage(msg)
    currentTime = m.top.video.position
    If currentTime > 3 And not m.top.adPlaying
       m.top.video.enableTrickPlay = true
    End If
  end while
End Sub

Function addCallbacks() as Void
  m.streamManager.addEventListener(m.sdk.AdEvent.ERROR, errorCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.START, startCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.FIRST_QUARTILE, firstQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.MIDPOINT, midpointCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.THIRD_QUARTILE, thirdQuartileCallback)
  m.streamManager.addEventListener(m.sdk.AdEvent.COMPLETE, completeCallback)
End Function

Function startCallback(ad as Object) as Void
  print "Callback from SDK -- Start called - "
End Function

Function firstQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- First quartile called - "
End Function

Function midpointCallback(ad as Object) as Void
  print "Callback from SDK -- Midpoint called - "
End Function

Function thirdQuartileCallback(ad as Object) as Void
  print "Callback from SDK -- Third quartile called - "
End Function

Function completeCallback(ad as Object) as Void
  print "Callback from SDK -- Complete called - "
End Function

Function errorCallback(error as Object) as Void
  print "Callback from SDK -- Error called - "; error
  m.errorState = True
End Function

افزودن پشتیبانی برای تبلیغات قابل رد شدن (اختیاری)

به منظور پشتیبانی از تبلیغات قابل پرش، باید یک روش seek را به شی پخش کننده IMA DAI SDK اضافه کنید که به صورت برنامه‌ریزی ویدیو را در مکان مشخص شده در ثانیه ممیز شناور جستجو کند.

برای پشتیبانی از تبلیغات قابل پرش، باید مطمئن شوید که adUiNode را در درخواست خود تنظیم کرده اید.

Sdk.xml

  m.player.loadUrl = Function(urlData)
    m.top.video.enableTrickPlay = false
    m.top.urlData = urlData
  End Function

  m.player.seek = Function(timeSeconds as Float)
     print "---- SDK requested seek to ----" ; timeSeconds
     m.top.video.seekMode = "accurate"
     m.top.video.seek = timeSeconds
  End Function

  m.player.adBreakStarted = Function(adBreakInfo as Object)
    print "---- Ad Break Started ---- "
    m.top.adPlaying = True
    m.top.video.enableTrickPlay = false
  End Function