Начать

Stay organized with collections Save and categorize content based on your preferences.

IMA SDK упрощают интеграцию мультимедийной рекламы на ваши веб-сайты и в приложения. SDK IMA могут запрашивать рекламу с любого рекламного сервера , совместимого с VAST , и управлять воспроизведением рекламы в ваших приложениях. С помощью IMA DAI SDK приложения отправляют запросы на потоковую передачу рекламы и видеоконтента — либо VOD, либо живого контента. Затем SDK возвращает комбинированный видеопоток, так что вам не нужно управлять переключением между рекламой и контентом в приложении.

В этом руководстве показано, как интегрировать IMA SDK в простое приложение видеопроигрывателя. Если вы хотите просмотреть готовый образец интеграции или следовать ему, загрузите базовый пример с GitHub.

Обзор IMA DAI

Внедрение IMA DAI включает в себя два основных компонента SDK, которые демонстрируются в этом руководстве:

  • StreamRequest : объект, определяющий запрос потока. Запросы потоков могут быть как для видео по запросу, так и для прямых трансляций. В запросах указывается идентификатор контента, а также ключ API или токен аутентификации и другие параметры.
  • StreamManager : объект, который обрабатывает потоки динамической вставки рекламы и взаимодействие с серверной частью DAI. Диспетчер потоков также обрабатывает запросы на отслеживание и перенаправляет потоковые и рекламные события издателю.

Предпосылки

Прежде чем начать, вам необходимо:

  • Прочтите нашу страницу совместимости, чтобы убедиться, что ваш предполагаемый вариант использования поддерживается.
  • Загрузите наш пример кода проигрывателя Roku .
  • Разверните приведенный выше пример кода проигрывателя на устройстве Roku, чтобы убедиться, что ваша настройка разработки работает.

Воспроизвести свое видео

Предоставленный образец видеопроигрывателя воспроизводит видеоконтент из коробки. Разверните образец проигрывателя на своем проигрывателе Roku, чтобы убедиться, что ваша среда разработки настроена правильно.

Превратите свой видеоплеер в потоковый проигрыватель динамической вставки рекламы IMA.

Создать SDK.xml

Добавьте в свой проект новый файл вместе с MainScene.xml с именем Sdk.xml и добавьте следующий шаблон:

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 SDK зависит от Roku Advertising Framework. Чтобы загрузить фреймворк, добавьте в manifest и Sdk.xml :

манифест
bs_libs_required=roku_ads_lib,googleima3
SDK.xml
Library "Roku_Ads.brs"
Library "IMA3.brs"

Загрузите SDK IMA

Первым шагом к загрузке потока динамической вставки рекламы IMA является загрузка и инициализация SDK IMA. Далее загружается сценарий IMA 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
  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
End Sub

Создание и выполнение потокового запроса

Теперь, когда у вас есть потоковый проигрыватель, вы можете создать и выполнить потоковый запрос. В этом примере есть данные для прямой трансляции и VOD-потока. В настоящее время используется поток VOD. Чтобы использовать live вместо 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: "Live Stream",
    assetKey: "sN_IYUG8STe1ZzhIIE_ksA",
    apiKey: "",
    type: "live"
  }
  m.testVodStream = {
    title: "VOD stream"
    contentSourceId: "2528370",
    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 = {}
  if m.top.streamData.type = "live"
    request = sdk.CreateLiveStreamRequest(m.top.streamData.assetKey, m.top.streamData.apiKey)
  else if m.top.streamData.type = "vod"
    request = sdk.CreateVodStreamRequest(m.top.streamData.contentSourceId, m.top.streamData.videoId, m.top.streamData.apiKey)
  else
    request = sdk.CreateStreamRequest()
  end if

  request.player = m.player
  request.adUiNode = m.top.video
  request.videoObject = m.top.video

  requestResult = sdk.requestStream(request)
  If requestResult <> 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"] <> 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. Крайне важно, чтобы вы перенаправляли все сообщения в 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