There are a number of other problems with the sample, including only supporting SD resolution, requiring the Roku to switch to 720p - which my monitor does not support.
I went and looked at the access logs - the file is not being referenced.
Using wireshark seemed to show up nothing, but it can be a difficult tool to use and I'm not 100% sure I'm capturing all the traffic I need too.
So what else can we do? Well, the debugger looks promising.
04-19 19:53:03.969 [beacon.signal] |AppLaunchInitiate ---------> TimeBase(0)
04-19 19:53:03.972 [beacon.signal] |AppCompileInitiate --------> TimeBase(3 ms)
04-19 19:53:03.973 [scrpt.cmpl] Compiling 'Hello World', id 'dev'
04-19 19:53:03.992 [scrpt.load.mkup] Loading markup dev 'Hello World'
04-19 19:53:03.999 [scrpt.unload.mkup] Unloading markup dev 'Hello World'
04-19 19:53:04.008 [scrpt.parse.mkup.time] Parsed markup dev 'Hello World' in 16 milliseconds
------ Compiling dev 'Hello World' ------
04-19 19:53:04.028 [scrpt.ctx.cmpl.time] Compiled 'Hello World', id 'dev' in 13 milliseconds
04-19 19:53:04.041 [scrpt.proc.mkup.time] Processed markup dev 'Hello World' in 9 milliseconds
04-19 19:53:04.046 [beacon.signal] |AppCompileComplete --------> Duration(74 ms), 2.14 KiP
04-19 19:53:04.084 [ui.frm.plugin.running.enter] Entering PLUGIN_RUNNING for dev
04-19 19:53:04.086 [beacon.signal] |AppLaunchInitiate ---------> TimeBase(0)
04-19 19:53:06.727 [scrpt.ctx.run.enter] UI: Entering 'Hello World', id 'dev'
------ Running dev 'Hello World' main ------
in showChannelSGScreen
OK, well, so far, so good. We have the message telling us it is setting up the screen. But then ... nothing.
The instructions say to press "Ctrl C", so I do that and am rewarded with a slew of information and then a debugger prompt. Excellent.
^C
BrightScript Micro Debugger.
Enter any BrightScript statement, debug commands, or HELP.
Suspending threads...
Thread selected: 0* pkg:/source/Main.brs(20) msg = wait(0, m.port)
Current Function:
012: m.port = CreateObject("roMessagePort")
013: screen.setMessagePort(m.port)
014:
015: 'Create a scene and load /components/helloworld.xml'
016: scene = screen.CreateScene("HelloWorld")
017: screen.show()
018:
019: while(true)
020:* msg = wait(0, m.port)
021: msgType = type(msg)
022: if msgType = "roSGScreenEvent"
023: if msg.isScreenClosed() then return
024: end if
Break in 20
020: msg = wait(0, m.port)
Backtrace:
#0 Function main() As Void
file/line: pkg:/source/Main.brs(20)
Local Variables:
global Interface:ifGlobal
m roAssociativeArray refcnt=2 count:1
screen roSGScreen refcnt=1
scene roSGNode:HelloWorld refcnt=1
msg <uninitialized>
msgtype <uninitialized>
Threads:
ID Location Source Code
0* pkg:/source/Main.brs(20) msg = wait(0, m.port)
*selected
Brightscript Debugger>
What I think I want to do is dig into the video component, but how to find it? There's a command bsc which lists all the active components. Let's try that.
Brightscript Debugger> bsc
roGlobal refcnt=1 [<roGlobal>]
roAssociativeArray refcnt=2 [{port:<roMessagePort>}]
roSGScreen refcnt=1 [<roSGScreen>]
roList refcnt=1 [L[]]
roMessagePort refcnt=2 [<roMessagePort>]
roSGNode:HelloWorld refcnt=1 [<roSGNode>]
6 component(s) total.
On second thoughts, I'm intimidated by that. I'm not quite sure what do with that. Let's try another tack. The listing above showed me the variables that are in scope, so let's try looking into those. The scene seems like the root of everything good, so let's print that and see what we get.
Brightscript Debugger> print scene
<Component: roSGNode:PlayVideo> =
{
backExitsScene: true
backgroundColor: 589505535
backgroundUri: ""
currentDesignResolution: <Component: roAssociativeArray>
dialog: <Component: roInvalid>
limitBackgroundToUIResolution: true
childRenderOrder: "last"
clippingRect: <Component: roAssociativeArray>
enableRenderTracking: false
inheritParentOpacity: true
inheritParentTransform: true
muteAudioGuide: false
opacity: 1
renderPass: 0
renderTracking: "disabled"
rotation: 0
scale: <Component: roArray>
scaleRotateCenter: <Component: roArray>
translation: <Component: roArray>
visible: true
change: <Component: roAssociativeArray>
focusable: true
focusedChild: <Component: roSGNode:Video>
id: ""
}
I feel this should have a list of children but I'm not really seeing that. But there is a focusedChild which is the Video component, so that seems like it might be worth further investigation.
Brightscript Debugger> print scene.focusedChild
<Component: roSGNode:Video> =
{
allowOptionsKeyOverride: false
alwaysShowVideoPlanes: false
audioFormat: ""
audioTrack: ""
autoPlayAfterSeek: true
availableAudioTracks: <Component: roArray>
availableSubtitleTracks: <Component: roArray>
bifDisplay: <Component: roSGNode:BifDisplay>
bufferingBar: <Component: roSGNode:ProgressBar>
bufferingBarVisibilityAuto: true
bufferingBarVisibilityBounds: <Component: roAssociativeArray>
bufferingBarVisibilityHint: false
bufferingStatus: invalid
bufferingTextColor: 0
capFontPath: ""
capFontSize: 0
captionStyle: invalid
cgms: "norestriction"
clipId: 0
completedStreamInfo: invalid
content: <Component: roInvalid>
contentBlocked: false
contentIndex: -1
contentIsPlaylist: false
control: "play"
currentAudioTrack: ""
currentSubtitleTrack: ""
disableScreenSaver: false
downloadedSegment: invalid
duration: 0
enableScreenSaverWhilePlaying: false
enableTrickPlay: true
enableUI: true
errorCode: -4
errorInfo: <Component: roAssociativeArray>
errorMsg: "No streams were provided for playback."
errorStr: "player agent play"
globalCaptionMode: "Instant replay"
height: 0
licenseStatus: invalid
loop: false
manifestData: invalid
maxVideoDecodeResolution: <Component: roArray>
mute: false
nextContentIndex: -1
notificationInterval: 0.5
pauseBufferEnd: 0
pauseBufferOverflow: false
pauseBufferPosition: 0
pauseBufferStart: 0
position: 0
retrievingBar: <Component: roSGNode:ProgressBar>
retrievingBarVisibilityAuto: true
retrievingBarVisibilityBounds: <Component: roAssociativeArray>
retrievingBarVisibilityHint: true
retrievingTextColor: 0
seek: 0
seekClip: invalid
state: "error"
streamInfo: invalid
streamingSegment: invalid
subtitleTrack: ""
supplementaryAudioVolume: 50
suppressCaptions: false
thumbnailTiles: invalid
timedMetaData: invalid
timedMetaData2: invalid
timedMetaDataSelectionKeys: <Component: roArray>
timeToStartStreaming: 0
tracks: <Component: roArray>
trickPlayBackground: <Component: roInvalid>
trickPlayBar: <Component: roSGNode:TrickPlayBar>
trickPlayBarVisibilityAuto: true
trickPlayBarVisibilityHint: false
videoFormat: ""
width: 0
childRenderOrder: "last"
clippingRect: <Component: roAssociativeArray>
enableRenderTracking: false
inheritParentOpacity: true
inheritParentTransform: true
muteAudioGuide: false
opacity: 1
renderPass: 0
renderTracking: "disabled"
rotation: 0
scale: <Component: roArray>
scaleRotateCenter: <Component: roArray>
translation: <Component: roArray>
visible: true
change: <Component: roAssociativeArray>
focusable: true
focusedChild: <Component: roSGNode:Video>
id: "playit"
}
I don't know about you, but what jumps out to me in this are the error fields:
errorCode: -4
errorInfo: <Component: roAssociativeArray>
errorMsg: "No streams were provided for playback."
errorStr: "player agent play"
No streams were provided for playback? What? Were you not looking? Oh, and by the way, thanks for hiding a fairly important error message deep in your object hierarchy rather than printing it out on the console where we can all benefit ...
I checked my model number and OS level in the Settings/System/About screen to make sure that everything I thought was supported really was and, yes, I'm on the latest version of the OS and my model - a 2710X - is still supported.
The console stream - while not telling me about the small matter of there not being any streams - did keep telling me that my streamformat wasn't valid. I couldn't - and still can't - figure out why that would be. But it made me start to think about XML and types. In XML everything is an element or a string. But that doesn't mean that the two are interchangeable.
And it occurred to me that although I was setting the content to what seemed like a reasonable value, that the Roku might be expecting an element rather than a string. Comparing what I'd done to what the sample application had done, I realized that they had done a lot more in their component's init() method, possibly for a good reason.
I reworked my playvideo.xml as follows:
What do you know? It works.
Debugging BrightScript
I don't really know what I'm doing, so I'm guessing based on the description in the previous post.
I run up the application and wait for it to hang. While I'm doing this, it spits out a bunch of debug statements:
04-19 19:53:03.972 [beacon.signal] |AppCompileInitiate --------> TimeBase(3 ms)
04-19 19:53:03.973 [scrpt.cmpl] Compiling 'Hello World', id 'dev'
04-19 19:53:03.992 [scrpt.load.mkup] Loading markup dev 'Hello World'
04-19 19:53:03.999 [scrpt.unload.mkup] Unloading markup dev 'Hello World'
04-19 19:53:04.008 [scrpt.parse.mkup.time] Parsed markup dev 'Hello World' in 16 milliseconds
------ Compiling dev 'Hello World' ------
04-19 19:53:04.028 [scrpt.ctx.cmpl.time] Compiled 'Hello World', id 'dev' in 13 milliseconds
04-19 19:53:04.041 [scrpt.proc.mkup.time] Processed markup dev 'Hello World' in 9 milliseconds
04-19 19:53:04.046 [beacon.signal] |AppCompileComplete --------> Duration(74 ms), 2.14 KiP
04-19 19:53:04.084 [ui.frm.plugin.running.enter] Entering PLUGIN_RUNNING for dev
04-19 19:53:04.086 [beacon.signal] |AppLaunchInitiate ---------> TimeBase(0)
04-19 19:53:06.727 [scrpt.ctx.run.enter] UI: Entering 'Hello World', id 'dev'
------ Running dev 'Hello World' main ------
in showChannelSGScreen
OK, well, so far, so good. We have the message telling us it is setting up the screen. But then ... nothing.
The instructions say to press "Ctrl C", so I do that and am rewarded with a slew of information and then a debugger prompt. Excellent.
^C
BrightScript Micro Debugger.
Enter any BrightScript statement, debug commands, or HELP.
Suspending threads...
Thread selected: 0* pkg:/source/Main.brs(20) msg = wait(0, m.port)
Current Function:
012: m.port = CreateObject("roMessagePort")
013: screen.setMessagePort(m.port)
014:
015: 'Create a scene and load /components/helloworld.xml'
016: scene = screen.CreateScene("HelloWorld")
017: screen.show()
018:
019: while(true)
020:* msg = wait(0, m.port)
021: msgType = type(msg)
022: if msgType = "roSGScreenEvent"
023: if msg.isScreenClosed() then return
024: end if
Break in 20
020: msg = wait(0, m.port)
Backtrace:
#0 Function main() As Void
file/line: pkg:/source/Main.brs(20)
Local Variables:
global Interface:ifGlobal
m roAssociativeArray refcnt=2 count:1
screen roSGScreen refcnt=1
scene roSGNode:HelloWorld refcnt=1
msg <uninitialized>
msgtype <uninitialized>
Threads:
ID Location Source Code
0* pkg:/source/Main.brs(20) msg = wait(0, m.port)
*selected
Brightscript Debugger>
What I think I want to do is dig into the video component, but how to find it? There's a command bsc which lists all the active components. Let's try that.
Brightscript Debugger> bsc
roGlobal refcnt=1 [<roGlobal>]
roAssociativeArray refcnt=2 [{port:<roMessagePort>}]
roSGScreen refcnt=1 [<roSGScreen>]
roList refcnt=1 [L[]]
roMessagePort refcnt=2 [<roMessagePort>]
roSGNode:HelloWorld refcnt=1 [<roSGNode>]
6 component(s) total.
On second thoughts, I'm intimidated by that. I'm not quite sure what do with that. Let's try another tack. The listing above showed me the variables that are in scope, so let's try looking into those. The scene seems like the root of everything good, so let's print that and see what we get.
Brightscript Debugger> print scene
<Component: roSGNode:PlayVideo> =
{
backExitsScene: true
backgroundColor: 589505535
backgroundUri: ""
currentDesignResolution: <Component: roAssociativeArray>
dialog: <Component: roInvalid>
limitBackgroundToUIResolution: true
childRenderOrder: "last"
clippingRect: <Component: roAssociativeArray>
enableRenderTracking: false
inheritParentOpacity: true
inheritParentTransform: true
muteAudioGuide: false
opacity: 1
renderPass: 0
renderTracking: "disabled"
rotation: 0
scale: <Component: roArray>
scaleRotateCenter: <Component: roArray>
translation: <Component: roArray>
visible: true
change: <Component: roAssociativeArray>
focusable: true
focusedChild: <Component: roSGNode:Video>
id: ""
}
I feel this should have a list of children but I'm not really seeing that. But there is a focusedChild which is the Video component, so that seems like it might be worth further investigation.
Brightscript Debugger> print scene.focusedChild
<Component: roSGNode:Video> =
{
allowOptionsKeyOverride: false
alwaysShowVideoPlanes: false
audioFormat: ""
audioTrack: ""
autoPlayAfterSeek: true
availableAudioTracks: <Component: roArray>
availableSubtitleTracks: <Component: roArray>
bifDisplay: <Component: roSGNode:BifDisplay>
bufferingBar: <Component: roSGNode:ProgressBar>
bufferingBarVisibilityAuto: true
bufferingBarVisibilityBounds: <Component: roAssociativeArray>
bufferingBarVisibilityHint: false
bufferingStatus: invalid
bufferingTextColor: 0
capFontPath: ""
capFontSize: 0
captionStyle: invalid
cgms: "norestriction"
clipId: 0
completedStreamInfo: invalid
content: <Component: roInvalid>
contentBlocked: false
contentIndex: -1
contentIsPlaylist: false
control: "play"
currentAudioTrack: ""
currentSubtitleTrack: ""
disableScreenSaver: false
downloadedSegment: invalid
duration: 0
enableScreenSaverWhilePlaying: false
enableTrickPlay: true
enableUI: true
errorCode: -4
errorInfo: <Component: roAssociativeArray>
errorMsg: "No streams were provided for playback."
errorStr: "player agent play"
globalCaptionMode: "Instant replay"
height: 0
licenseStatus: invalid
loop: false
manifestData: invalid
maxVideoDecodeResolution: <Component: roArray>
mute: false
nextContentIndex: -1
notificationInterval: 0.5
pauseBufferEnd: 0
pauseBufferOverflow: false
pauseBufferPosition: 0
pauseBufferStart: 0
position: 0
retrievingBar: <Component: roSGNode:ProgressBar>
retrievingBarVisibilityAuto: true
retrievingBarVisibilityBounds: <Component: roAssociativeArray>
retrievingBarVisibilityHint: true
retrievingTextColor: 0
seek: 0
seekClip: invalid
state: "error"
streamInfo: invalid
streamingSegment: invalid
subtitleTrack: ""
supplementaryAudioVolume: 50
suppressCaptions: false
thumbnailTiles: invalid
timedMetaData: invalid
timedMetaData2: invalid
timedMetaDataSelectionKeys: <Component: roArray>
timeToStartStreaming: 0
tracks: <Component: roArray>
trickPlayBackground: <Component: roInvalid>
trickPlayBar: <Component: roSGNode:TrickPlayBar>
trickPlayBarVisibilityAuto: true
trickPlayBarVisibilityHint: false
videoFormat: ""
width: 0
childRenderOrder: "last"
clippingRect: <Component: roAssociativeArray>
enableRenderTracking: false
inheritParentOpacity: true
inheritParentTransform: true
muteAudioGuide: false
opacity: 1
renderPass: 0
renderTracking: "disabled"
rotation: 0
scale: <Component: roArray>
scaleRotateCenter: <Component: roArray>
translation: <Component: roArray>
visible: true
change: <Component: roAssociativeArray>
focusable: true
focusedChild: <Component: roSGNode:Video>
id: "playit"
}
I don't know about you, but what jumps out to me in this are the error fields:
errorCode: -4
errorInfo: <Component: roAssociativeArray>
errorMsg: "No streams were provided for playback."
errorStr: "player agent play"
No streams were provided for playback? What? Were you not looking? Oh, and by the way, thanks for hiding a fairly important error message deep in your object hierarchy rather than printing it out on the console where we can all benefit ...
One Day Later
Not really knowing what else to do, I walked away. But I kept turning this over in my mind and from time to time googling this and that as they occurred to me.I checked my model number and OS level in the Settings/System/About screen to make sure that everything I thought was supported really was and, yes, I'm on the latest version of the OS and my model - a 2710X - is still supported.
The console stream - while not telling me about the small matter of there not being any streams - did keep telling me that my streamformat wasn't valid. I couldn't - and still can't - figure out why that would be. But it made me start to think about XML and types. In XML everything is an element or a string. But that doesn't mean that the two are interchangeable.
And it occurred to me that although I was setting the content to what seemed like a reasonable value, that the Roku might be expecting an element rather than a string. Comparing what I'd done to what the sample application had done, I realized that they had done a lot more in their component's init() method, possibly for a good reason.
I reworked my playvideo.xml as follows:
<?xml version="1.0" encoding="utf-8" ?><component name="PlayVideo" extends="Scene"> <children> <ContentNode id="damian" url="http://www.gmmapowell.com/downloads/Damian2018.mp4" StreamFormat="mp4" /> <Video id="playit" control="play" width="0" height="0" /> </children><script type="text/brightscript" ><![CDATA[ function init() video = m.top.findNode("playit") video.content = m.top.findNode("damian") video.setFocus(true) video.control = "play" end function]]></script></component>This still creates the two components using XML, but connects them using BrightScript and "finding" the content node to attach it to the video node.
What do you know? It works.
Summary
Debugging a Roku application is much like debugging anything else - it's equal parts tools, investigation and inspiration. This problem was solved by finding out what the problem was using the debugger, then applying research and inspiration to understand what could be the issue and then fixing it.
The result is the ability to what some quality Chiefs' rugby
The result is the ability to what some quality Chiefs' rugby
No comments:
Post a Comment