เริ่มต้นใช้งาน IMA DAI SDK

IMA SDK ช่วยให้การผสานรวมโฆษณามัลติมีเดียลงในเว็บไซต์และแอปเป็นเรื่องง่าย IMA SDK สามารถขอโฆษณาจากเซิร์ฟเวอร์โฆษณาที่ สอดคล้องกับ VAST และจัดการการเล่นโฆษณาในแอปของคุณ เมื่อใช้ IMA DAI SDK แอปจะส่งคำขอสตรีมสำหรับโฆษณาและวิดีโอเนื้อหาไม่ว่าจะเป็น VOD หรือเนื้อหาสด จากนั้น SDK จะแสดงสตรีมวิดีโอแบบรวมเพื่อให้คุณไม่ต้องจัดการการสลับระหว่างโฆษณาและวิดีโอเนื้อหาภายในแอป

เลือกโซลูชัน DAI ที่สนใจ

DAI สำหรับบริการเต็มรูปแบบ

คู่มือนี้สาธิตวิธีผสานรวม IMA SDK เข้ากับแอปโปรแกรมเล่นวิดีโออย่างง่าย หากต้องการดูหรือทำตามการผสานรวมตัวอย่างที่สมบูรณ์ ให้ดาวน์โหลดตัวอย่างพื้นฐานจาก GitHub

ภาพรวม IMA DAI

การใช้งาน IMA DAI ประกอบด้วยองค์ประกอบ SDK หลัก 2 ส่วนดังที่แสดงในคู่มือนี้

  • StreamRequest: ออบเจ็กต์ที่กำหนดคำขอสตรีม คำขอสตรีมอาจเป็นได้ทั้งวิดีโอออนดีมานด์หรือสตรีมแบบสด คำขอจะระบุ Content ID รวมทั้งคีย์ API หรือโทเค็นการตรวจสอบสิทธิ์ และพารามิเตอร์อื่นๆ
  • StreamManager: ออบเจ็กต์ที่จัดการสตรีมการแทรกโฆษณาแบบไดนามิกและการโต้ตอบกับแบ็กเอนด์ DAI ตัวจัดการสตรีมจะจัดการกับคำสั่ง ping ของการติดตาม รวมถึงส่งต่อเหตุการณ์ของสตรีมและเหตุการณ์โฆษณาไปยังผู้เผยแพร่โฆษณาด้วย

ข้อกำหนดเบื้องต้น

เล่นวิดีโอ

วิดีโอเพลเยอร์ตัวอย่างที่ให้มาเล่นวิดีโอเนื้อหาได้ทันที ใช้โปรแกรมเล่นตัวอย่างกับโปรแกรมเล่นของ Roku เพื่อให้แน่ใจว่ามีการตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์อย่างถูกต้อง

เปลี่ยนโปรแกรมเล่นวิดีโอเป็นสตรีมเพลเยอร์ของ IMA DAI

ทำตามขั้นตอนต่อไปนี้เพื่อติดตั้งใช้งานโปรแกรมเล่นสตรีม

สร้าง 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>

คุณต้องแก้ไขทั้ง 2 ไฟล์ในคู่มือนี้

โหลดเฟรมเวิร์กการโฆษณาของ Roku

IMA SDK ขึ้นอยู่กับเฟรมเวิร์กการโฆษณาของ Roku หากต้องการโหลดเฟรมเวิร์ก ให้เพิ่มข้อมูลต่อไปนี้ลงใน manifest และ Sdk.xml

ไฟล์ Manifest

bs_libs_required=roku_ads_lib,googleima3

Sdk.xml

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

โหลด IMA SDK

ขั้นตอนแรกของการโหลดสตรีมการแทรกโฆษณาแบบไดนามิก IMA คือการโหลดและเริ่มต้น IMA SDK แท็กต่อไปนี้จะโหลดสคริปต์ 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 สตรีมเพลเยอร์นี้ใช้วิธีการเรียกกลับ 3 วิธี ได้แก่ loadUrl, adBreakStarted และ adBreakEnded แล้วก็ปิดใช้ Trick Play เมื่อโหลดสตรีมอยู่ วิธีนี้จะป้องกันไม่ให้ผู้ใช้ข้ามโฆษณาตอนต้นทันทีที่เริ่ม ก่อนที่เหตุการณ์การเริ่มช่วงพักโฆษณาจะเริ่มทำงาน

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 เช่น ไอคอนตัวเลือกโฆษณาอื่นๆ คุณต้องส่งการอ้างอิงไปยังโหนดที่มีวิดีโอเนื้อหาของคุณเป็นส่วนหนึ่งของคำขอด้วย

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

เพิ่ม Listener เหตุการณ์และเริ่มสตรีม

หลังจากขอสตรีมแล้ว ก็เหลือสิ่งที่ต้องทำอีกเพียงไม่กี่ขั้นตอนเท่านั้น ได้แก่ เพิ่มตัวฟังเหตุการณ์เพื่อติดตามความคืบหน้าของโฆษณา เริ่มสตรีม และส่งต่อข้อความ 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 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