IMA SDK 可讓您輕鬆將多媒體廣告整合至網站和應用程式中。IMA SDK 可以向任何符合 VAST 規定的廣告伺服器請求廣告,並管理應用程式中的廣告播放作業。使用 IMA DAI SDK,應用程式可對廣告和內容影片 (即 VOD 或直播內容) 提出串流請求。接著,SDK 會傳回合併的影片串流,這樣您就不必在應用程式中切換廣告和內容影片的切換。
本指南說明如何將 IMA SDK 整合到簡易的影片播放器應用程式中。如想查看已完成的範例或按照已完成的範例整合,請從 GitHub 下載基本範例。
IMA DAI 總覽
導入 IMA DAI 包含兩個主要 SDK 元件,本指南將說明這些元件:
StreamRequest
:定義串流要求的物件。串流要求可以是隨選影片或直播。要求會指定內容 ID、API 金鑰或驗證權杖和其他參數。StreamManager
: 可處理動態廣告插播串流,以及與 DAI 後端互動的物件。串流管理員也會處理追蹤連線偵測 (ping),並將串流和廣告事件轉送至發布商。
必要條件
開始之前,您必須:
- 請詳閱相容性頁面,確認支援您的用途。
- 下載我們的 Roku 範例播放器程式碼。
- 將上述的播放器程式碼範例部署至 Roku 裝置,確認您的開發設定是否正常運作。
播放影片
您提供的影片播放器範例可立即播放內容影片。將範例播放器部署至 Roku 播放器,以確保開發環境設定正確。
將影片播放器轉換成 IMA 動態廣告插播串流播放器
建立 Sdk.xml
在專案中新增名為 Sdk.xml
的 MainScene.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 廣告架構。如要載入架構,請將以下內容新增至 manifest
和 Sdk.xml
:
資訊清單
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 串流播放器。
此串流播放器實作三種回呼方法: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 串流。如要使用直播而非 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