שנתחיל?

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

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

סקירה כללית של IMA DAI

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

  • StreamRequest: אובייקט שמגדיר בקשת שידור. הבקשות לסטרימינג יכולות להיות על פי דרישה (VOD) או בשידור חי. בבקשות מצוין מזהה תוכן, כמו גם מפתח API או אסימון אימות ופרמטרים אחרים.
  • StreamManager: אובייקט שמטפל בסטרימינג דינמי של הטמעת מודעות ובאינטראקציות עם הקצה העורפי של DAI. מנהל השידור גם מטפל בפינגים של מעקב ומעביר אירועים של אירועים ומודעות למפרסם.

דרישות מוקדמות

לפני שמתחילים:

  • כדאי לקרוא את דף התאימות שלנו כדי לוודא שתרחיש השימוש המיועד נתמך.
  • מורידים את קוד הנגן לדוגמה Roku.
  • צריך לפרוס את קוד הנגן לדוגמה שלמעלה במכשיר Roku כדי לוודא שהגדרת הפיתוח פועלת.

הפעלת הסרטון שלך

נגן הווידאו לדוגמה שסיפקת מפעיל סרטון תוכן מהאריזה. כדאי לפרוס את הנגן לדוגמה בנגן Roku כדי לוודא שסביבת הפיתוח מוגדרת נכון.

איך הופכים את נגן הווידאו לנגן הסטרימינג של מודעת IMA דינמית?

יצירת 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 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 ולהסיר את הקריאה כדי לטעון את תוכן התוכן.

מחשב ראשי
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
  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, כמו סמלים של AdChoice, צריך גם להעביר הפניה לצומת שמכיל את תוכן התוכן כחלק מהבקשה.

מחשב ראשי
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

הוספת פונקציות event listener והתחלת השידור

לאחר בקשת השידור, נותרו רק עוד כמה פעולות לעשות: להוסיף פונקציות event listener כדי לעקוב אחר התקדמות המודעות, להתחיל את השידור ולהעביר הודעות של Roku ל-SDK. חשוב מאוד להעביר את כל ההודעות ל-SDK כדי להבטיח הפעלה נכונה של מודעות.

מחשב ראשי
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