IMA SDK를 사용하면 웹사이트와 앱에 멀티미디어 광고를 쉽게 통합할 수 있습니다. IMA SDK는 VAST 호환 광고 서버에서 광고를 요청하고 앱에서 광고 재생을 관리할 수 있습니다. IMA DAI SDK를 사용하면 앱에서 광고 및 콘텐츠 동영상(VOD 또는 라이브 콘텐츠)의 스트림을 요청합니다. 그러면 SDK가 결합된 동영상 스트림을 반환하므로 앱 내에서 광고와 콘텐츠 동영상 간 전환을 관리하지 않아도 됩니다.
관심 있는 DAI 솔루션 선택
종합 서비스 DAI
이 가이드에서는 IMA DAI SDK를 간단한 동영상 플레이어 앱에 통합하는 방법을 보여줍니다. 완료된 샘플 통합을 확인하거나 따라 하려면 GitHub에서 기본 예시를 다운로드하세요.
IMA DAI 개요
IMA DAI를 구현하려면 이 가이드에 설명된 대로 두 가지 주요 SDK 구성요소가 필요합니다.
StreamRequest
: 스트림 요청을 정의하는 객체입니다. 스트림 요청은 주문형 비디오 또는 라이브 스트림에 대한 요청일 수 있습니다. 라이브 스트림 요청은 애셋 키를 지정하고 VOD 요청은 CMS ID와 동영상 ID를 지정합니다. 두 요청 유형 모두 지정된 스트림에 액세스하는 데 필요한 API 키와 IMA SDK가 Google Ad Manager 설정에 지정된 대로 광고 식별자를 처리하는 Google Ad Manager 네트워크 코드를 선택적으로 포함할 수 있습니다.StreamManager
: 동적 광고 삽입 스트림과 DAI 백엔드와의 상호작용을 처리하는 객체입니다. 스트림 관리자는 추적 핑을 처리하고 스트림 및 광고 이벤트를 게시자에게 전달합니다.
기본 요건
- 호환성 페이지를 읽고 사용 사례가 지원되는지 확인하세요.
- 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 광고 프레임워크 로드
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()
함수를 호출합니다.SDK 로드 이벤트에 응답하도록
onSdkLoaded()
및onSdkLoadedError()
리스너 서브루틴을 만듭니다.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()
서브루틴을 만듭니다. adChoices 아이콘과 같은 광고 UI를 지원하려면 콘텐츠 동영상을 포함하는 노드에 대한 참조도 요청의 일부로 전달해야 합니다.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 또는 라이브 스트림 중에서 선택합니다. 다음 예에는 라이브 스트림과 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
객체로 변경하여 대신 라이브 스트림을 사용할 수 있습니다.
스트림 시작
스트림 데이터를 수신 대기하고 playStream()
서브루틴을 호출하는 urlLoadRequested()
서브루틴을 만듭니다.
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
스트림 메타데이터 수신 대기
스트림 재생 중에 실행되고 StreamManager.onMessage()
를 사용하여 스트림 메타데이터를 IMA에 전송하는 while 루프로 runLoop()
서브루틴을 만듭니다.
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