使用 IMA SDK,即可輕鬆將多媒體廣告整合至網站和應用程式。IMA SDK 可向任何 符合 VAST 規定的廣告伺服器請求廣告,並在應用程式中管理廣告播放。應用程式可透過 IMA DAI SDK,對廣告和內容影片 (隨選影片或直播內容) 提出串流請求。SDK 接著會傳回合併的影片串流,因此您不必在應用程式中管理廣告和內容影片之間的切換。
選取您感興趣的 DAI 解決方案
全方位服務 DAI
本指南說明如何將 IMA DAI SDK 整合至簡易影片播放器應用程式。如要查看或跟著操作完整的範例整合,請從 GitHub 下載基本範例。
IMA DAI 總覽
如本指南所示,導入 IMA DAI 需要兩個主要 SDK 元件:
StreamRequest
: 定義串流要求的物件。串流要求可以是隨選影片或直播串流。直播串流請求會指定素材資源金鑰,而 VOD 請求則會指定 CMS ID 和影片 ID。這兩種要求類型都可以選擇性地加入存取指定串流所需的 API 金鑰,以及 Google Ad Manager 聯播網代碼,供 IMA SDK 處理廣告 ID,如 Google Ad Manager 設定中所指定。StreamManager
: 這個物件會處理動態廣告插播串流,以及與 DAI 後端的互動。串流管理工具也會處理追蹤 Ping,並將串流和廣告事件轉送給發布商。
必要條件
- 請詳閱相容性頁面,確認您預期的用途是否受到支援。
- 下載 Roku 範例播放器程式碼
- 將範例播放器程式碼部署到 Roku 裝置,確認開發設定正常運作。
播放影片
提供的範例影片播放器可直接播放內容影片。將範例播放器部署至 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>
在本指南中,您需要編輯這兩個檔案。
載入 Roku Advertising Framework
IMA DAI SDK 依附於 Roku 廣告架構。如要載入架構,請在 manifest
和 Sdk.xml
中加入下列內容:
bs_libs_required=roku_ads_lib,googleima3
Library "Roku_Ads.brs"
Library "IMA3.brs"
載入 IMA DAI SDK
如要載入 IMA DAI SDK,請按照下列步驟操作:
使用
New_IMASDK()
呼叫初始化 IMA SDK:sub loadSdk() If m.sdk = invalid m.sdk = New_IMASDK() End If m.top.sdkLoaded = true End Sub
建立
sdkLoaded
布林值欄位,追蹤 IMA 是否已載入:<field id="sdkLoaded" type="Boolean" />
從主要
runThread()
副常式呼叫loadSdk()
副常式:if not m.top.sdkLoaded loadSdk() End If
在
MainScene.xml
中建立loadImaSdk()
函式,以建立及執行sdkTask
物件:function loadImaSdk() as void m.sdkTask = createObject("roSGNode", "imasdk") m.sdkTask.observeField("sdkLoaded", "onSdkLoaded") m.sdkTask.observeField("errors", "onSdkLoadedError") ' Change to m.testLiveStream to demo live instead of VOD. selectedStream = m.testVodStream m.videoTitle = selectedStream.title m.sdkTask.streamData = selectedStream m.sdkTask.observeField("urlData", "urlLoadRequested") m.sdkTask.video = m.video ' Setting control to run starts the task thread. m.sdkTask.control = "RUN" end function
從
init()
函式呼叫loadImaSdk()
函式。建立
onSdkLoaded()
和onSdkLoadedError()
接聽程式子常式,以回應 SDK 載入事件: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 串流播放器
如要建立 IMA 串流播放器,請按照下列步驟操作:
建立可執行下列作業的
setupVideoPlayer()
副程式:使用
createPlayer()
方法建立串流播放器。讓該串流播放器實作三種回呼方法:
loadUrl
、adBreakStarted
和adBreakEnded
。載入串流時停用快轉功能,避免使用者在串流開始時,於廣告中斷開始事件觸發前略過片頭廣告。
sub setupVideoPlayer() sdk = m.sdk m.player = sdk.createPlayer() m.player.top = m.top m.player.loadUrl = Function(urlData) ' This line prevents users from scanning during buffering ' or during the first second of the ad before we have a callback from roku. ' If there are no prerolls disabling trickplay isn't needed. 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 Double) print "---- SDK requested seek to ----" ; timeSeconds m.top.video.seekMode = "accurate" m.top.video.seek = timeSeconds End Function End Sub
新增
seek
回呼方法,支援可略過的廣告。詳情請參閱「新增支援可略過廣告」。新增
setupVideoPlayer()
副程式中使用的urlData
、adPlaying
和video
欄位:<field id="urlData" type="assocarray" /> <field id="adPlaying" type="Boolean" /> <field id="video" type="Node" />
建立及執行串流要求
如要要求 DAI 串流,請按照下列步驟操作:
建立
loadStream()
副常式,以建立及要求串流。如要支援廣告使用者介面 (例如「廣告選擇」圖示),您也必須在要求中傳遞含有內容影片的節點參照:Sub loadStream() sdk = m.sdk sdk.initSdk() setupVideoPlayer() request = {} streamData = m.top.streamData if streamData.type = "live" request = sdk.CreateLiveStreamRequest(streamData.assetKey, streamData.apiKey, streamData.networkCode) else if streamData.type = "vod" request = sdk.CreateVodStreamRequest(streamData.contentSourceId, streamData.videoId, streamData.apiKey, streamData.networkCode) else request = sdk.CreateStreamRequest() end if request.player = m.player request.adUiNode = 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
在
loadStream()
副常式中新增streamData
和streamManagerReady
欄位:<field id="streamManagerReady" type="Boolean" /> <field id="streamData" type="assocarray" />
如果沒有串流管理員,請從
runThread()
副常式呼叫loadStream()
副常式:if not m.top.streamManagerReady loadStream() End If
選取 VOD 或直播。以下範例包含直播和隨選影片串流的串流參數:
m.testLiveStream = { title: "Live Stream", assetKey: "c-rArva4ShKVIAkNfy6HUQ", networkCode: "21775744923", apiKey: "", type: "live" } m.testVodStream = { title: "VOD stream" contentSourceId: "2548831", videoId: "tears-of-steel", networkCode: "21775744923", apiKey: "", type: "vod" }
根據預設,本指南會使用 VOD 串流。您可以將
m.testVodStream
物件的selectedStream
變數變更為m.testLiveStream
物件,改用直播。
開始直播
建立 urlLoadRequested()
副常式,監聽串流資料並呼叫 playStream()
副常式:
Sub urlLoadRequested(message as Object)
print "Url Load Requested ";message
data = message.getData()
playStream(data.manifest, data.format)
End Sub
建立 playStream()
,開始播放串流:
Sub playStream(url as String, format as String)
vidContent = createObject("RoSGNode", "ContentNode")
vidContent.url = url
vidContent.title = m.videoTitle
vidContent.streamformat = format
m.video.content = vidContent
m.video.setFocus(true)
m.video.visible = true
m.video.control = "play"
m.video.EnableCookies()
End Sub
監聽串流中繼資料
使用 while 迴圈建立 runLoop()
副常式,在串流播放期間執行,並使用 StreamManager.onMessage()
將串流中繼資料傳送至 IMA:
Sub runLoop()
' Forward all timed metadata events.
m.top.video.timedMetaDataSelectionKeys = ["*"]
' Cycle through all the fields and just listen to them all.
m.port = CreateObject("roMessagePort")
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
' Only enable trickplay after a few seconds, in case we start with an ad,
' to prevent users from skipping through that ad.
If currentTime > 3 And not m.top.adPlaying
m.top.video.enableTrickPlay = true
End If
end while
End Sub
監聽廣告事件
現在您已將串流中繼資料傳遞至 IMA,IMA 就能在廣告插播期間發出廣告事件。視需要建立廣告事件監聽器,以便回應廣告事件:
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
' errors are critical and should terminate the stream.
m.errorState = True
End Function
新增對可略過廣告的支援 (選用)
如要支援可略過廣告,您需要在 IMA DAI SDK 的 player 物件中加入 seek
方法,以程式輔助方式將影片搜尋至指定位置 (以浮點秒數表示)。
如要支援可略過廣告,請務必在要求中設定 adUiNode
。
m.player.seek = Function(timeSeconds as Double)
print "---- SDK requested seek to ----" ; timeSeconds
m.top.video.seekMode = "accurate"
m.top.video.seek = timeSeconds
End Function