我当前正在与roku开发人员插件一起使用eclipse IDE来创建通道。我有编程和代码方面的经验,但是Brightscript对我来说很难找到自己的舒适感。
我成功地创建了一个足够流式传输的通道。我现在要做的是测试皇家空军的包含。我已经尝试查看现有RAF模板的代码以及我当前的工作流程序。
不幸的是,呼叫和变量名称足够不同,我的无知足够高,我正在努力连接一些点。当我包括RAF库和代码或我认为需要的代码时,当我按下播放按钮时,视频不再播放。频道加载和预览/详细信息加载,当我按播放什么都不做。
这是页面上代码的该部分的代码。
Sub onItemSelected()
' first button is Play
if m.top.itemSelected = 0
m.videoPlayer = CreateObject("roSGNode", "Video")
m.videoPlayer.id="videoPlayer"
m.videoPlayer.translation="[0, 0]"
m.videoPlayer.width="1280"
m.videoPlayer.height="720"
m.videoPlayer.content = m.top.content
'show video player
m.top.AppendChild(m.videoPlayer)
m.videoPlayer.visible = true
m.videoPlayer.setFocus(true)
m.videoPlayer.control = "play"
m.videoPlayer.observeField("state", "OnVideoPlayerStateChange")
m.videoPlayer.observeField("visible", "onVideoVisibleChange")
'THIS IS THE CODE I ADDED FROM THE RAF EXAMPLE
'EVERYTHING IN BELOW THIS UNTIL THE END OF THE
'SUB IF REMOVED THE VIDEO PLAYS.
'--------------------------------------------------------------------------------
adIface = Roku_Ads() 'RAF initialize
print "Roku_Ads library version: " + adIface.getLibVersion()
adIface.setDebugOutput(true) 'for debug pupropse
'Indicates whether the default Roku backfill ad service URL
'should be used in case the client-configured URL fails (2 retries)
'to return any renderable ads.
adIface.setAdPrefs(true, 2)
' Normally, would set publisher's ad URL here. Uncomment following line to do so.
' adIface.setAdUrl(m.videoContent.adUrl)
' Otherwise uses default Roku ad server (with single preroll placeholder ad)
'Returns available ad pod(s) scheduled for rendering or invalid, if none are available.
adPods = adIface.getAds()
playContent = true
'render pre-roll ads
if adPods <> invalid and adPods.count() > 0 then
playContent = adIface.showAds(adPods)
endif
while(true)
msg = wait(0, m.port)
msgType = type(msg)
if msgType = "roSGScreenEvent"
if msg.isScreenClosed() then return
else if msgType = "roSGNodeEvent"
if (msg.GetNode() = "DetailsScreen")
if msg.GetField() = "position" then
'render mid-roll ads
curPos = m.video.position
videoEvent = createPlayPosMsg(curPos)
adPods = adIface.getAds(videoEvent)
if adPods <> invalid and adPods.count() > 0
m.video.control = "stop"
playContent = adIface.showAds(adPods)
if playContent then
m.video.seek = curPos
m.video.control = "play"
endif
endif
else if msg.GetField() = "state" then
curState = m.video.state
if curState = "finished" then
'render post-roll ads
videoEvent = createPlayPosMsg(curPos, true)
adPods = adIface.getAds(videoEvent)
m.video.control = "stop"
if adPods <> invalid and adPods.count() > 0
adIface.showAds(adPods)
end if
exit while
endif
else if msg.GetField() = "navBack" then
'back button handling
if msg.GetData() = true then
m.video.control = "stop"
exit while
endif
end if
end if
end if
end while
'----------------------------------------------------------------------
'THIS IS THE END OF THE RAF CODE I INSERTED INTO THE VIDEO TEMPLATE.
end if
End Sub
在日食上,这给了我一个错误,我尝试研究和弄清楚,但是正如我提到的那样,我被卡住了。
Current Function:
086: m.videoPlayer.control = "play"
087: m.videoPlayer.observeField("state", "OnVideoPlayerStateChange")
088: m.videoPlayer.observeField("visible", "onVideoVisibleChange")
089:
090: 'THIS IS THE CODE I ADDED FROM THE RAF EXAMPLE
091: 'EVERYTHING IN BELOW THIS UNTIL THE END OF THE
092: 'SUB IF REMOVED THE VIDEO PLAYS.
093: '--------------------------------------------------------------------------------
094:* adIface = Roku_Ads() 'RAF initialize
095: print "Roku_Ads library version: " + adIface.getLibVersion()
096:
097: adIface.setDebugOutput(true) 'for debug pupropse
098:
Function Call Operator ( ) attempted on non-function. (runtime error &he0) in pkg:/components/screens/DetailsScreen/DetailsScreen.brs(94)
094: adIface = Roku_Ads() 'RAF initialize
Backtrace:
#0 Function onitemselected() As Void
file/line: pkg:/components/screens/DetailsScreen/DetailsScreen.brs(94)
Local Variables:
global Interface:ifGlobal
m roAssociativeArray refcnt=2 count:7
adiface <uninitialized>
adpods <uninitialized>
playcontent <uninitialized>
msg <uninitialized>
msgtype <uninitialized>
curpos <uninitialized>
videoevent <uninitialized>
curstate <uninitialized>
roku_ads <uninitialized>
createplayposmsg <uninitialized>
Threads:
ID Location Source Code
0 pkg:/source/main.brs(34) msg = wait(0, port)
1* ...ailsScreen/DetailsScreen.brs(94) adIface = Roku_Ads() 'RAF initialize
*selected
Brightscript Debugger>
我希望缩小如何修改我的频道以完成这项工作。我确实忽略了此代码:
'RAF content params
adIface.setContentId(m.videoContent.contentId)
adIface.SetContentGenre(m.videoContent.contentGenre)
'Nielsen content params
adIface.enableNielsenDAR(true)
adIface.setContentLength(m.videoContent.conntentLength)
adIface.setNielsenProgramId(m.videoContent.nielsenProgramId)
adIface.setNielsenGenre(m.videoContent.nielsenGenre)
adIface.setNielsenAppId(m.videoContent.nielsenAppId)
不想与尼尔森的东西一起工作,但不确定我是否需要包含它才能使皇家空军工作。
真的,谢谢您的时间。
确保您的文件顶部导入库:
Library "Roku_Ads.brs"
和清单文件中的条目:
bs_libs_required=roku_ads_lib
还要注意,您无法从渲染线程调用RAF - 这将是下一个问题,查看您的代码。应该从主线程或任务线程完成(请参阅https://github.com/rokudev/raf4rsg-sample)。
谢谢大家的帮助。纳斯·班诺夫(Nas Banov),我查看了您链接到Github的RAF示例,我想我明白我需要做什么,只是很难看这条路。
我实际上添加了Sepleate .BRS文件以按照您的建议来处理RAF实现。该视频从外部XML文档中加载到网格中,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title></title>
<link />
<description></description>
<language></language>
<pubDate></pubDate>
<image>
<title></title>
<url></url>
<width>-1</width>
<height>-1</height>
</image>
<item>
<title></title>
<link></link>
<description></description>
<pubDate></pubDate>
<guid isPermaLink="false"></guid>
<media:content channels="2" bitrate="1328.0" duration="53"
fileSize="8731706" framerate="23.976" height="720"
type="video/mp4" width="1280" isDefault="true" url="">
<media:description></media:description>
<media:keywords></media:keywords>
<media:thumbnail url="" />
<media:title></media:title>
</media:content>
</item>
</channel>
</rss>
我正在考虑将Nielson的必要字段添加到此XML,如果我找到了将XML条目推入RAF集成进行报告的方法。
这是菜单选择的详细信息部分。按下网格布局上的按钮后,详细信息屏幕加载。在这里,我引用playerTasks.brs,其中包含RAF集成代码。
' ********** Copyright 2016 Roku Corp. All Rights Reserved. **********
' inits details screen
' sets all observers
' configures buttons for Details screen
Function Init()
? "[DetailsScreen] init"
m.top.observeField("visible", "onVisibleChange")
m.top.observeField("focusedChild", "OnFocusedChildChange")
m.buttons = m.top.findNode("Buttons")
m.poster = m.top.findNode("Poster")
m.description = m.top.findNode("Description")
m.background = m.top.findNode("Background")
' create buttons
result = []
for each button in ["Play", "Second button"]
result.push({title : button})
end for
m.buttons.content = ContentList2SimpleNode(result)
m.top.content=m.buttons.content
End Function
' set proper focus to buttons if Details opened and stops Video if Details closed
Sub onVisibleChange()
? "[DetailsScreen] onVisibleChange"
if m.top.visible = true then
m.buttons.jumpToItem = 0
m.buttons.setFocus(true)
else if m.videoPlayer <> invalid
m.videoPlayer.visible = false
m.videoPlayer.control = "stop"
m.poster.uri=""
m.background.uri=""
end if
End Sub
' set proper focus to Buttons in case if return from Video PLayer
Sub OnFocusedChildChange()
if m.top.isInFocusChain() and not m.buttons.hasFocus() and not m.videoPlayer.hasFocus() then
m.buttons.setFocus(true)
end if
End Sub
' set proper focus on buttons and stops video if return from Playback to details
Sub onVideoVisibleChange()
if m.videoPlayer.visible = false and m.top.visible = true
m.buttons.setFocus(true)
m.videoPlayer.control = "stop"
'clear video player content, for proper start of next video player
m.videoPlayer.content = invalid
'remove video player
m.top.removeChild(m.videoPlayer)
end if
End Sub
' event handler of Video player msg
Sub OnVideoPlayerStateChange()
if m.videoPlayer.state = "error"
' error handling
m.videoPlayer.visible = false
else if m.videoPlayer.state = "playing"
' playback handling
playContent()
else if m.videoPlayer.state = "finished"
m.videoPlayer.visible = false
end if
End Sub
sub playContent()
content = m.buttons.content
if content <> invalid then
m.video.content = content
m.video.visible = false
m.PlayerTask = CreateObject("roSGNode", "PlayerTask")
m.PlayerTask.observeField("state", "taskStateChanged")
m.PlayerTask.video = m.video
m.PlayerTask.control = "RUN"
end if
end sub
sub taskStateChanged(event as Object)
print "Player: taskStateChanged(), id = "; event.getNode(); ", "; event.getField(); " = "; event.getData()
state = event.GetData()
if state = "done" or state = "stop"
exitPlayer()
end if
end sub
' on Button press handler
Sub onItemSelected()
' first button is Play
if m.top.itemSelected = 0
m.videoPlayer = CreateObject("roSGNode", "Video")
m.videoPlayer.id="videoPlayer"
m.videoPlayer.translation="[0, 0]"
m.videoPlayer.width="1280"
m.videoPlayer.height="720"
m.videoPlayer.content = m.top.content
'show video player
m.top.AppendChild(m.videoPlayer)
m.videoPlayer.visible = true
m.videoPlayer.setFocus(true)
m.videoPlayer.control = "play"
m.videoPlayer.observeField("state", "OnVideoPlayerStateChange")
m.videoPlayer.observeField("visible", "onVideoVisibleChange")
end if
End Sub
' Content change handler
Sub OnContentChange()
m.description.content = m.top.content
m.description.Description.width = "770"
m.poster.uri = m.top.content.hdBackgroundImageUrl
m.background.uri = m.top.content.hdBackgroundImageUrl
End Sub
'///////////////////////////////////////////'
' Helper function convert AA to Node
Function ContentList2SimpleNode(contentList as Object, nodeType = "ContentNode" as String) as Object
result = createObject("roSGNode",nodeType)
if result <> invalid
for each itemAA in contentList
item = createObject("roSGNode", nodeType)
item.setFields(itemAA)
result.appendChild(item)
end for
end if
return result
End Function
Function OnkeyEvent(key, press) as Boolean
? ">>> Details >> OnkeyEvent"
result = false
if press AND key = "back" AND m.videoPlayer <> invalid AND m.videoPlayer.visible
m.videoPlayer.visible = false
result = true
end if
return result
End Function
i添加了" PlayContent"子例程,该子例程指向.brs文件,并带有RAF集成。当我注意到它丢失时,添加了任务史学事件。我陷入了[m.playertask.video = m.video]
的部分表达式左侧的无效值。(运行时错误&amp; he4)
似乎无法弄清楚我可以将解析的XML文档的值传递到PlayerTasks部分以使其正常工作。我知道我需要做的事情只是找不到足够容易的文档来获取它。
'*********************************************************************
'** (c) 2016-2017 Roku, Inc. All content herein is protected by U.S.
'** copyright and other applicable intellectual property laws and may
'** not be copied without the express permission of Roku, Inc., which
'** reserves all rights. Reuse of any of this content for any purpose
'** without the permission of Roku, Inc. is strictly prohibited.
'*********************************************************************
Library "Roku_Ads.brs"
sub init()
m.top.functionName = "playContentWithAds"
m.top.id = "PlayerTask"
end sub
sub playContentWithAds()
video = m.top.video
' `view` is the node under which RAF should display its UI (passed as 3rd argument of showAds())
view = video.getParent()
RAF = Roku_Ads()
'RAF.clearAdBufferScreenLayers() ' in case it was set earlier
'RAF.enableAdBufferMessaging(true, true) ' could have been cleared by custom screen
'RAF.setAdBufferScreenContent({})
content = video.content
RAF.setAdUrl(content.ad_url)
' for generic measurements api
RAF.setContentGenre(content.categories) 'if unset, ContentNode has it as []
' Nielsen DAR specific measurements
if content.nielsen_app_id <> invalid:
RAF.enableNielsenDAR(true)
RAF.setNielsenAppId(content.nielsen_app_id)
RAF.setNielsenGenre(content.nielsen_genre)
RAF.setNielsenProgramId(content.nielsen_program_id)
RAF.setContentLength(content.length)
end if
' log tracking events
' logObj = {
' log : Function(evtType = invalid as Dynamic, ctx = invalid as Dynamic)
' if GetInterface(evtType, "ifString") <> invalid
' print "*** tracking event " + evtType + " fired."
' if ctx.companion = true then
' print "***** companion = true"
' end if
' if ctx.errMsg <> invalid then print "***** Error message: " + ctx.errMsg
' if ctx.adIndex <> invalid then print "***** Ad Index: " + ctx.adIndex.ToStr()
' if ctx.ad <> invalid and ctx.ad.adTitle <> invalid then print "***** Ad Title: " + ctx.ad.adTitle
' else if ctx <> invalid and ctx.time <> invalid
' print "*** checking tracking events for ad progress: " + ctx.time.ToStr()
' end if
' End Function
' }
' logFunc = Function(obj = Invalid as Dynamic, evtType = invalid as Dynamic, ctx = invalid as Dynamic)
' obj.log(evtType, ctx)
' End Function
' RAF.setTrackingCallback(logFunc, logObj)
adPods = RAF.getAds() 'array of ad pods
keepPlaying = true 'gets set to `false` when showAds() was exited via Back button
' show the pre-roll ads, if any
if adPods <> invalid and adPods.count() > 0
keepPlaying = RAF.showAds(adPods, invalid, view)
end if
port = CreateObject("roMessagePort")
if keepPlaying then
video.observeField("position", port)
video.observeField("state", port)
video.visible = true
video.control = "play"
video.setFocus(true) 'so we can handle a Back key interruption
end if
curPos = 0
adPods = invalid
isPlayingPostroll = false
while keepPlaying
msg = wait(0, port)
if type(msg) = "roSGNodeEvent"
if msg.GetField() = "position" then
' keep track of where we reached in content
curPos = msg.GetData()
' check for mid-roll ads
adPods = RAF.getAds(msg)
if adPods <> invalid and adPods.count() > 0
print "PlayerTask: mid-roll ads, stopping video"
'ask the video to stop - the rest is handled in the state=stopped event below
video.control = "stop"
end if
else if msg.GetField() = "state" then
curState = msg.GetData()
print "PlayerTask: state = "; curState
if curState = "stopped" then
if adPods = invalid or adPods.count() = 0 then
exit while
end if
print "PlayerTask: playing midroll/postroll ads"
keepPlaying = RAF.showAds(adPods, invalid, view)
adPods = invalid
if isPlayingPostroll then
exit while
end if
if keepPlaying then
print "PlayerTask: mid-roll finished, seek to "; stri(curPos)
video.visible = true
video.seek = curPos
video.control = "play"
video.setFocus(true) 'important: take the focus back (RAF took it above)
end if
else if curState = "finished" then
print "PlayerTask: main content finished"
' render post-roll ads
adPods = RAF.getAds(msg)
if adPods = invalid or adPods.count() = 0 then
exit while
end if
print "PlayerTask: has postroll ads"
isPlayingPostroll = true
' stop the video, the post-roll would show when the state changes to "stopped" (above)
video.control = "stop"
end if
end if
end if
end while
print "PlayerTask: exiting playContentWithAds()"
end sub
谢谢大家帮助我解决这个问题。自从我专注于软件开发以来,情况发生了很大变化。