IMA SDK 可讓您輕鬆將多媒體廣告整合至您的網站和應用程式。IMA SDK 可以從任何 符合 VAST 規定的廣告伺服器請求廣告,並管理在應用程式中播放的廣告。使用 IMA DAI SDK 時,應用程式會向廣告和內容影片 (VOD 或直播內容) 發出串流請求。接著,SDK 會傳回合併的影片串流,因此您不必在應用程式中切換廣告和內容影片。
選取所需的 DAI 解決方案
完整服務 DAI
本指南說明如何將 IMA DAI SDK 整合到簡單的影片播放器應用程式中。如果您要查看或按照完成整合的範例整合,請前往 GitHub 下載基本範例。
IMA DAI 總覽
導入 IMA DAI 需要兩個主要的 SDK 元件,如本指南所示:
StreamRequest
:定義串流要求的物件。串流要求可以是隨選影片或直播要求。要求會指定內容 ID,以及 API 金鑰或驗證權杖和其他參數。StreamManager
: 這個物件會處理動態廣告插播串流,以及與 DAI 後端的互動。串流管理員也會處理追蹤連線偵測 (ping),並將串流和廣告事件轉寄給發布商。
先備知識
- 請詳閱相容性頁面,確認系統支援您預期的用途。
- 下載 Roku 播放器範例程式碼
- 將範例播放器程式碼部署至 Roku 裝置,驗證開發設定是否可正常運作。
播放影片
提供的影片播放器範例會隨即播放內容影片。將範例播放器部署至 Roku 播放器,確認開發環境設定正確無誤。
將您的影片播放器轉換成 IMA DAI 串流播放器
請按照下列步驟實作串流播放器。
建立 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 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 <> 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。
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
新增可略過的廣告支援 (選用)
如果要支援可略過廣告,您必須在 IMA DAI SDK 的 Player 物件中新增 seek
方法,以程式輔助方式將影片尋找指定位置 (以浮點秒為單位)。
若要支援可略過的廣告,您也必須在請求中設定 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