کیتهای توسعه نرمافزار IMA ادغام تبلیغات چندرسانهای را در وبسایتها و برنامههای شما آسان میکنند. کیتهای توسعه نرمافزار IMA میتوانند از هر سرور تبلیغاتی سازگار با VAST درخواست تبلیغات کنند و پخش تبلیغات را در برنامههای شما مدیریت کنند. با کیتهای توسعه نرمافزار IMA DAI، برنامهها درخواست پخش جریانی برای تبلیغات و ویدیوی محتوا - چه VOD و چه محتوای زنده - ارسال میکنند. سپس SDK یک جریان ویدیویی ترکیبی را برمیگرداند، به طوری که شما مجبور نیستید جابجایی بین ویدیوی تبلیغ و محتوا را در برنامه خود مدیریت کنید.
راهکار DAI مورد نظرتان را انتخاب کنید
این راهنما نحوه پخش زنده یا استریم VOD سرویس DAI Pod Serving را با استفاده از IMA DAI SDK برای Roku نشان میدهد. برای مشاهده یا دنبال کردن یک نمونه تکمیلشده از یکپارچهسازی، نمونه Pod Serving را دانلود کنید.
نمای کلی سرویس غلاف IMA DAI
پیادهسازی سرویس پاد با استفاده از IMA DAI شامل دو جزء اصلی SDK است که در این راهنما نشان داده شدهاند:
-
StreamRequest.createPodLiveStreamRequest()/StreamRequest.createPodVodStreamRequest(): یک شیء ایجاد میکند که درخواست پخش جریان را به سرورهای تبلیغات گوگل تعریف میکند. این درخواستها یک کد شبکه را مشخص میکنند و Pod Liveima.StreamRequestهمچنین به یک کلید دارایی سفارشی و یک کلید API اختیاری نیاز دارد. -
StreamManager: شیءای که ارتباط بین جریان ویدئو و IMA DAI SDK را مدیریت میکند، مانند اجرای پینگهای ردیابی و ارسال رویدادهای جریان به ناشر.
علاوه بر این، شما باید یک درخواست به سرور دستکاری مانیفست خود ارسال کنید تا مانیفست جریان را برای نمایش برنامه شما بازیابی کند. فرآیند دقیق میتواند از VTP شریک فناوری ویدیو (VTP) به VTP دیگر متفاوت باشد.
پیشنیازها
- برای اطمینان از اینکه مورد استفاده مورد نظر شما پشتیبانی میشود، صفحه سازگاری ما را مطالعه کنید.
- کد پخش کننده نمونه 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>
شما باید هر دو فایل ( MainScene.xml و Sdk.xml ) را در طول این راهنما ویرایش کنید.
فریمورک IMA DAI SDK را بارگذاری کنید
برای بارگذاری فریمورک، موارد زیر را به manifest و Sdk.xml اضافه کنید:
آشکار
bs_libs_required=googleima3
SDK.xml
<?xml version = "1.0" encoding = "utf-8" ?>
<component name = "imasdk" extends = "Task">
<interface>
</interface>
<script type = "text/brightscript">
<![CDATA[
Library "IMA3.brs"
]]>
</script>
</component>
مقداردهی اولیه IMA DAI SDK
اولین قدم برای بارگذاری جریان درج آگهی پویای IMA، بارگذاری و مقداردهی اولیه IMA DAI SDK است. دستور زیر اسکریپت IMA DAI SDK را مقداردهی اولیه میکند.
SDK.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="IMASDKTask" extends="Task">
<interface>
<field id="IMASDKInitialized" type="Boolean" />
<field id="errors" type="stringarray" />
</interface>
<script type = "text/brightscript">
<![CDATA[
Library "IMA3.brs"
sub init()
m.top.functionName = "runThread"
end sub
sub runThread()
if not m.top.IMASDKInitialized
initializeIMASDK()
end if
end sub
sub initializeIMASDK()
if m.sdk = invalid
m.sdk = New_IMASDK()
end if
m.top.IMASDKInitialized = true
end sub
]]>
</script>
</component>
حالا این وظیفه را در MainScene.xml شروع کنید و فراخوانی برای بارگذاری جریان محتوا را حذف کنید.
صحنه اصلی.xml
<?xml version="1.0" encoding="utf-8" ?>
<component extends="Scene" initialFocus="myVideo" name="MainScene">
<script type="text/brightscript">
<![CDATA[
function init()
m.video = m.top.findNode("myVideo")
m.video.notificationinterval = 1
runIMASDKTask()
end function
function runIMASDKTask()
m.IMASDKTask = createObject("roSGNode", "IMASDKTask")
m.IMASDKTask.observeField("IMASDKInitialized", "handleIMASDKInitialized")
m.IMASDKTask.observeField("errors", "handleIMASDKErrors")
m.IMASDKTask.control = "RUN"
end function
sub handleIMASDKInitialized()
' Follow your manifest manipulator (VTP) documentation to register a user
' streaming session if needed.
end sub
sub handleIMASDKErrors(message as object)
print "------ IMA DAI SDK failed ------"
if message <> invalid and message.getData() <> invalid
print "IMA DAI SDK Error ";message.getData()
end if
end sub
]]>
</script>
<children>
<Video height="720" id="myVideo" visible="false" width="1280"/>
</children>
</component>
یک پخشکننده جریان IMA ایجاد کنید
در مرحله بعد، باید از roVideoScreen موجود خود برای ایجاد یک پخشکننده جریان IMA استفاده کنید.
پخش زنده سرو پاد
برای پخش زنده، این پخشکنندهی پخش، سه متد فراخوانی را پیادهسازی میکند: streamInitialized ، adBreakStarted و adBreakEnded .
همچنین هنگام بارگذاری پخش زنده، ترفند پخش را غیرفعال کنید. این کار مانع از آن میشود که کاربران در لحظه شروع پخش، قبل از اجرای رویداد شروع پخش تبلیغات، از آن صرف نظر کنند.
SDK.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="IMASDKTask" extends="Task">
<interface>
<field id="IMASDKInitialized" type="Boolean" />
<field id="errors" type="stringarray" />
<field id="urlData" type="assocarray" />
<field id="adPlaying" type="Boolean" />
<field id="videoNode" type="Node" />
</interface>
<script type="text/brightscript">
...
sub runThread()
if not m.top.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
end sub
...
sub initializeIMASDK()
if m.ima = invalid
ima = New_IMASDK()
ima.initSdk()
m.ima = ima
end if
m.top.IMASDKInitialized = true
end sub
sub setupPlayerCallbacks()
m.player = m.ima.createPlayer()
m.player.top = m.top
m.player.streamInitialized = function(urlData)
m.top.videoNode.enableTrickPlay = false
m.top.urlData = urlData
end function
m.player.adBreakStarted = function(adBreakInfo)
print "------ Ad break started ------"
m.top.adPlaying = true
m.top.videoNode.enableTrickPlay = false
end function
m.player.adBreakEnded = function(adBreakInfo)
print "------ Ad break ended ------"
m.top.adPlaying = false
m.top.videoNode.enableTrickPlay = true
end function
end sub
</script>
...
</component>
سرویس پخش پاد VOD
برای استریمهای VOD، این پخشکنندهی استریم چهار متد فراخوانی را پیادهسازی میکند: streamInitialized ، loadUrl ، adBreakStarted و adBreakEnded . در فراخوانی streamInitialized ، حتماً StreamManager.loadThirdPartyStream() را فراخوانی کنید. عدم انجام این کار منجر به عدم اجرای تابع loadUrl توسط SDK خواهد شد.
در این مرحله، شما همچنین از شریک فناوری ویدیوی خود (VTP) یک URL استریم با شناسه استریم به دست آمده در loadAdPodStream() درخواست میکنید. سپس، StreamManager.loadThirdPartyStream() با مانیفست ad pod و هر زیرنویسی که توسط VTP شما برگردانده میشود، فراخوانی کنید.
همچنین هنگام بارگذاری پخش زنده، ترفند پخش را غیرفعال کنید. این کار مانع از آن میشود که کاربران در لحظه شروع پخش، قبل از اجرای رویداد شروع پخش تبلیغات، از آن صرف نظر کنند.
SDK.xml
<?xml version="1.0" encoding="utf-8" ?>
<component name="IMASDKTask" extends="Task">
<interface>
<field id="IMASDKInitialized" type="Boolean" />
<field id="errors" type="stringarray" />
<field id="adStitchedStreamInfo" type="assocarray" />
<field id="adPlaying" type="Boolean" />
<field id="videoNode" type="Node" />
<field id="streamParameters" type="assocarray" />
</interface>
<script type="text/brightscript">
...
sub runThread()
if not m.top.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
end sub
...
sub initializeIMASDK()
if m.ima = invalid
ima = New_IMASDK()
ima.initSdk()
m.ima = ima
end if
m.top.IMASDKInitialized = true
end sub
sub loadThirdPartyStream(adStitchedManifest as string, subtitleConfig as dynamic)
m.streamManager.loadThirdPartyStream(adStitchedManifest, subtitleConfig)
end sub
sub setupPlayerCallbacks()
m.player = m.ima.createPlayer()
m.player.top = m.top
m.player.streamInitialized = function(urlData)
adStitchedManifest = m.top.streamParameters.VTPManifest.replace("[[STREAMID]]", urlData.streamId)
loadThirdPartyStream(adStitchedManifest, m.top.streamParameters.subtitleConfig)
end function
m.player.loadUrl = function(streamInfo)
m.top.adStitchedStreamInfo = streamInfo
end function
m.player.adBreakStarted = function(adBreakInfo)
print "------ Ad break started ------"
m.top.adPlaying = true
m.top.videoNode.enableTrickPlay = false
end function
m.player.adBreakEnded = function(adBreakInfo)
print "------ Ad break ended ------"
m.top.adPlaying = false
m.top.videoNode.enableTrickPlay = true
end function
end sub
</script>
...
</component>
درخواست پخش زنده یا VOD Pod Serving را ایجاد و اجرا کنید
بعد از اینکه یک پخشکنندهی جریان (stream player) داشتید، میتوانید یک درخواست جریان (stream request) ایجاد و اجرا کنید. این مثال دادههایی برای یک جریان Pod Serving دارد که در m.testPodServingStream ذخیره شده است.
پخش زنده سرو پاد
در شیء m.testPodServingStream ، پارامترهایی را که Google Ad Manager برای شناسایی جریان مورد نظر نیاز دارد، مانند کد شبکه و کلید دارایی سفارشی، ذخیره کنید. همچنین URL مانیفست مورد استفاده برای دسترسی به سرور دستکاری مانیفست خود را ذخیره کنید. در این حالت، URL مانیفست باید پس از بازگشت درخواست جریان، شناسه Google Stream را داشته باشد.
برای اینکه بتوانید از AdUI، مانند آیکونهای adChoices، پشتیبانی کنید، باید به عنوان بخشی از درخواست خود، یک ارجاع به گره حاوی ویدیوی محتوای خود نیز ارسال کنید.
صحنه اصلی.xml
function init()
m.video = m.top.findNode("myVideo")
m.video.notificationinterval = 1
m.testPodServingStream = {
title: "Test live stream for DAI Pod Serving",
assetKey: "test-live-stream",
networkCode: "your-network-code",
manifest: "https://.../master.m3u8?stream_id=[[STREAMID]]",
apiKey: ""
}
runIMASDKTask()
end function
function runIMASDKTask()
m.IMASDKTask = createObject("roSGNode", "IMASDKTask")
m.IMASDKTask.streamParameters = m.testPodservingStream
m.IMASDKTask.videoNode = m.video
m.IMASDKTask.observeField("IMASDKInitialized", "handleIMASDKInitialized")
m.IMASDKTask.observeField("errors", "handleIMASDKErrors")
m.IMASDKTask.control = "RUN"
end function
SDK.xml
<interface>
<field id="IMASDKInitialized" type="Boolean" />
<field id="errors" type="stringarray" />
<field id="urlData" type="assocarray" />
<field id="adPlaying" type="Boolean" />
<field id="videoNode" type="Node" />
<field id="streamParameters" type="assocarray" />
</interface>
...
sub runThread()
if not m.top.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
loadAdPodStream()
end sub
sub loadAdPodStream()
request = m.ima.CreatePodLiveStreamRequest(m.top.streamParameters.assetKey, m.top.streamParameters.networkCode, m.top.streamParameters.apiKey)
' Set the player object so that the request can trigger the player's
' callbacks at stream initialization or playback events.
request.player = m.player
' Set the video node for the IMA DAI SDK to create ad UI as its child nodes.
request.adUiNode = m.top.video
requestResult = m.ima.requestStream(request)
if requestResult <> invalid
print "Error requesting stream ";requestResult
return
end if
m.streamManager = invalid
while m.streamManager = invalid
sleep(50)
m.streamManager = m.ima.getStreamManager()
end while
if m.streamManager = invalid
errors = CreateObject("roArray", 1, True)
invalidStreamManagerError = "Invalid stream manager"
print invalidStreamManagerError
errors.push(invalidStreamManagerError)
m.top.errors = errors
return
end if
if m.streamManager["type"] <> invalid and m.streamManager["type"] = "error"
errors = CreateObject("roArray", 1, True)
print "Stream request returns an error. " ; m.streamManager["info"]
errors.push(m.streamManager["info"])
m.top.errors = errors
return
end if
setupStreamManager()
m.streamManager.start()
end sub
سرویس پخش پاد VOD
در شیء m.testPodServingStream ، کد شبکه مورد استفاده در درخواست جریان را ذخیره خواهید کرد، بنابراین Google Ad Manager میتواند یک شناسه جریان ارائه دهد. همچنین URL مانیفست مورد استفاده برای دسترسی به مانیفست خاص کاربر در سرور دستکاری مانیفست خود را ذخیره کنید.
برای اینکه بتوانید از AdUI، مانند آیکونهای adChoices، پشتیبانی کنید، باید به عنوان بخشی از درخواست خود، یک ارجاع به گره حاوی ویدیوی محتوای خود نیز ارسال کنید.
صحنه اصلی.xml
sub init()
m.video = m.top.findNode("myVideo")
m.video.notificationinterval = 1
m.testPodServingStream = {
title: "Pod Serving VOD Stream",
networkCode: "your-network-code",
VTPManifest: "https://.../manifest.m3u8?gam-stream-id=[[STREAMID]]",
subtitleConfig: []
}
runIMASDKTask()
end sub
sub runIMASDKTask()
m.IMASDKTask = createObject("roSGNode", "IMASDKTask")
m.IMASDKTask.streamParameters = m.testPodservingStream
m.IMASDKTask.videoNode = m.video
m.IMASDKTask.observeField("IMASDKInitialized", "handleIMASDKInitialized")
m.IMASDKTask.observeField("errors", "handleIMASDKErrors")
m.IMASDKTask.control = "RUN"
end sub
SDK.xml
sub runThread()
if not m.top.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
loadAdPodStream()
end sub
sub loadAdPodStream()
request = m.ima.CreatePodVodStreamRequest(m.top.streamParameters.networkCode)
' Set the player object so that the request can trigger the player
' callbacks at stream initialization or playback events.
request.player = m.player
' Set the video node for the IMA DAI SDK to create ad UI as its child nodes.
request.adUiNode = m.top.video
requestResult = m.ima.requestStream(request)
if requestResult <> invalid
print "Error requesting stream ";requestResult
return
end if
m.streamManager = invalid
while m.streamManager = invalid
sleep(50)
m.streamManager = m.ima.getStreamManager()
end while
if m.streamManager = invalid
errors = CreateObject("roArray", 1, True)
invalidStreamManagerError = "Invalid stream manager"
print invalidStreamManagerError
errors.push(invalidStreamManagerError)
m.top.errors = errors
return
end if
if m.streamManager["type"] <> invalid and m.streamManager["type"] = "error"
errors = CreateObject("roArray", 1, True)
print "Stream request returns an error. " ; m.streamManager["info"]
errors.push(m.streamManager["info"])
m.top.errors = errors
return
end if
setupStreamManager()
m.streamManager.start()
end sub
اضافه کردن شنوندههای رویداد و شروع پخش جریانی
پخش زنده سرو پاد
پس از درخواست پخش زنده، فقط چند کار باقی مانده است: اضافه کردن شنوندههای رویداد برای ردیابی پیشرفت تبلیغ و ارسال پیامهای Roku به SDK. مهم است که همه پیامها را به SDK ارسال کنید تا از پخش صحیح تبلیغ اطمینان حاصل شود. عدم انجام این کار منجر به گزارش نادرست بازدیدهای تبلیغ میشود.
در این مرحله، شما همچنین یک تابع برای جایگزینی ماکرو [[STREAMID]] با شناسه جریان اضافه میکنید و URL درخواست مانیفست تکمیلشده را به پخشکننده ویدیو ارسال میکنید. این پیادهسازی شناسه جریان را در این مرحله دریافت میکند، اما بسته به ادغام VTP شما، ممکن است قبل از این مرحله در دسترس باشد.
صحنه اصلی.xml
function runIMASDKTask()
m.IMASDKTask = createObject("roSGNode", "IMASDKTask")
m.IMASDKTask.streamParameters = m.testPodservingStream
m.IMASDKTask.videoNode = m.video
m.IMASDKTask.observeField("IMASDKInitialized", "handleIMASDKInitialized")
m.IMASDKTask.observeField("errors", "handleIMASDKErrors")
m.sdkTask.observeField("adStitchedStreamInfo", "loadAdStitchedStream")
m.sdkTask.control = "RUN"
end function
sub loadAdStitchedStream(message as object)
print "Ad pod stream information ";message
adPodStreamInfo = message.getData()
manifest = m.testPodservingStream.manifest.Replace("[[STREAMID]]", adPodStreamInfo.streamId)
playStream(manifest, adPodStreamInfo.format)
end sub
sub playStream(url as string, format as string)
vidContent = createObject("RoSGNode", "ContentNode")
vidContent.url = url
vidContent.title = m.testPodservingStream.title
vidContent.streamformat = format
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.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
loadAdPodStream()
if m.streamManager <> invalid
runLoop()
end if
end sub
sub runLoop()
m.top.videoNode.timedMetaDataSelectionKeys = ["*"]
' IMPORTANT: Failure to listen to the position and timedmetadata fields
' could result in ad impressions not being reported.
m.port = CreateObject("roMessagePort")
m.top.videoNode.observeField("position", m.port)
m.top.videoNode.observeField("timedMetaData", m.port)
m.top.videoNode.observeField("timedMetaData2", m.port)
m.top.videoNode.observeField("state", m.port)
while True
msg = wait(1000, m.port)
if m.top.videoNode = invalid
print "exiting"
exit while
end if
m.streamManager.onMessage(msg)
currentTime = m.top.videoNode.position
if currentTime > 3 And not m.top.adPlaying
m.top.videoNode.enableTrickPlay = true
end if
end while
end sub
sub setupStreamManager()
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 sub
sub startCallback(ad as object)
print "Callback from SDK -- Start called - "
end sub
sub firstQuartileCallback(ad as object)
print "Callback from SDK -- First quartile called - "
end sub
sub midpointCallback(ad as object)
print "Callback from SDK -- Midpoint called - "
end sub
sub thirdQuartileCallback(ad as object)
print "Callback from SDK -- Third quartile called - "
end sub
sub completeCallback(ad as object)
print "Callback from SDK -- Complete called - "
end sub
function errorCallback(error as object)
print "Callback from SDK -- Error called - " ; error
m.errorState = True
end function
سرویس پخش پاد VOD
پس از درخواست پخش زنده، فقط چند کار باقی مانده است: اضافه کردن شنوندههای رویداد برای ردیابی پیشرفت تبلیغ و ارسال پیامهای Roku به SDK. مهم است که همه پیامها را به SDK ارسال کنید تا از پخش صحیح تبلیغ اطمینان حاصل شود. عدم انجام این کار باعث میشود که بازدیدهای تبلیغ به طور نامناسب گزارش شوند.
صحنه اصلی.xml
sub runIMASDKTask()
m.IMASDKTask = createObject("roSGNode", "IMASDKTask")
m.IMASDKTask.streamParameters = m.testPodservingStream
m.IMASDKTask.videoNode = m.video
m.IMASDKTask.observeField("IMASDKInitialized", "handleIMASDKInitialized")
m.IMASDKTask.observeField("errors", "handleIMASDKErrors")
m.sdkTask.observeField("adStitchedStreamInfo", "loadAdStitchedStream")
m.sdkTask.control = "RUN"
end sub
sub loadAdStitchedStream(message as object)
print "Ad pod stream information ";message
adPodStreamInfo = message.getData()
end sub
sub playStream(url as string, format as string, subtitleConfig as object)
vidContent = createObject("RoSGNode", "ContentNode")
vidContent.title = m.testPodservingStream.title
vidContent.url = url
vidContent.subtitleConfig = subtitleConfig
vidContent.streamformat = format
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.IMASDKInitialized
initializeIMASDK()
end if
setupPlayerCallbacks()
loadAdPodStream()
if m.streamManager <> invalid
runLoop()
end if
end sub
sub runLoop()
m.top.videoNode.timedMetaDataSelectionKeys = ["*"]
' IMPORTANT: Failure to listen to the position and timedmetadata fields
' could result in ad impressions not being reported.
m.port = CreateObject("roMessagePort")
m.top.videoNode.observeField("position", m.port)
m.top.videoNode.observeField("timedMetaData", m.port)
m.top.videoNode.observeField("timedMetaData2", m.port)
m.top.videoNode.observeField("state", m.port)
while True
msg = wait(1000, m.port)
if m.top.videoNode = invalid
exit while
end if
m.streamManager.onMessage(msg)
currentTime = m.top.videoNode.position
if currentTime > 3 and not m.top.adPlaying
m.top.videoNode.enableTrickPlay = true
end if
end while
end sub
sub setupStreamManager()
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 sub
sub startCallback(ad as object)
print "Callback from SDK -- Start called - "
end sub
sub firstQuartileCallback(ad as object)
print "Callback from SDK -- First quartile called - "
end sub
sub midpointCallback(ad as object)
print "Callback from SDK -- Midpoint called - "
end sub
sub thirdQuartileCallback(ad as object)
print "Callback from SDK -- Third quartile called - "
end sub
sub completeCallback(ad as object)
print "Callback from SDK -- Complete called - "
end sub
sub errorCallback(error as object)
print "Callback from SDK -- Error called - " ; error
m.errorState = True
end sub