תחילת העבודה עם IMA DAI SDK

ערכות ה-SDK של IMA מאפשרות לשלב בקלות מודעות מולטימדיה באתרים ובאפליקציות. ערכות ה-SDK של IMA יכולות לבקש מודעות מכל שרת מודעות שתואם ל-VAST ולנהל את ההפעלה של המודעות באפליקציות. באמצעות ערכות ה-SDK של IMA DAI, האפליקציות שולחות בקשה לשידור של מודעת וידאו ותוכן וידאו – VOD או תוכן בשידור חי. לאחר מכן, ה-SDK מחזיר שידור וידאו משולב, כך שלא תצטרכו לנהל את המעבר בין סרטון המודעה לסרטון התוכן באפליקציה.

בחירת פתרון ה-DAI הרצוי

שירות DAI מלא

המדריך הזה מראה איך לשלב את IMA DAI SDK באפליקציית נגן וידאו פשוטה. אם אתם רוצים לראות דוגמה לשילוב מלא או לפעול לפיה, תוכלו להוריד את הדוגמה הבסיסית מ-GitHub.

סקירה כללית על הטמעת מודעות דינמיות (DAI) ב-IMA

הטמעת IMA DAI כוללת שני רכיבים עיקריים של SDK, כפי שמתואר במדריך הזה:

  • StreamRequest: אובייקט שמגדיר בקשת סטרימינג. בקשות להפעלת שידורים יכולות להיות לשידורים חיים או לשידורים לפי דרישה. הבקשות כוללות מזהה תוכן, מפתח API או אסימון אימות ופרמטרים אחרים.
  • 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

IMA DAI SDK תלוי ב-Roku Advertising Framework. כדי לטעון את המסגרת, מוסיפים את הטקסט הבא לקובצי manifest ו-Sdk.xml:

manifest

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. נגן הסטרימינג הזה מיישם שלוש שיטות קריאה חוזרת (callback): 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 &lt;&gt; 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"] &lt;&gt; 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

הוספת תמיכה במודעות שניתן לדלג עליהן (אופציונלי)

כדי לתמוך במודעות שניתן לדלג עליהן, צריך להוסיף את השיטה seek לאובייקט player של IMA DAI SDK, שמבצעת באופן פרוגרמטי חיפוש של הסרטון למיקום שצוין, בשניות של נקודה צפה.

כדי לתמוך במודעות שניתן לדלג עליהן, צריך גם להגדיר את הערך 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