In my Roku application I'm using scenegraph timegrid view and another custom view for audio content. I have an onkeyevent in the main.brs and additional ones in each of the main views (timegrid and audio content). The onkeyevents get propagated properly up the chain in the timegrid view as I'm overriding the "options" key to show a custom menu dialog to allow the user to switch between views. When in the audio content view, the onkeyevents are propagating properly from within RowLists and Groups up the chain. Only when I start an audio stream does the "options" key event seem to no be delivered to the onkeyevent as I have put logging statements to see the keys triggered.
So all other keyevents I listen for such as dpad movements and OK are being captured but the onkeyevent in the audio view but the "options" key is bringing up the standard roku options menu instead of being thrown up the chain to where it should be caught by the onkeyevent in the main. This only happens when I start the audio. Can someone explain to me what I'm doing wrong? Focus is not on the audio component as the Rowlist and other components get focus because i catch the focus events.
Thanks.
Edit:
I just checked if the audio is in the focus chain after I set the control to 'play' and its not.
OK pressed. Playing station. stopped Chain false OK 11-12 19:12:47.916 [beacon.signal] |LiveStartInitiate ---------> TimeBase(22828 ms) 11-12 19:12:47.916 [beacon.signal] |LiveStartComplete ---------> Duration(3766 ms)
Hi @devnullpointer,
Are you using the Video node or Audio node for this? Also, can you provide me with a sample channel so our engineering team can further help you?
Thanks,
Jonathan
Hi @RokuJonathanD ,
Sorry for the late reply. I'm using an Audio node. I've inserted the code from the XML and the BRS files respectively. The primeRadio function loads the contentNode from a TaskNode to the audio player. I then make sure the Scene gets the focus not the audio player, hoping this would solve the problem. Unfortunately as long as the audio player is playing and not "stop" then the keyevent never gets propagated up the chain. I've also added the onKeyEvent function to show I don't process the "*" key.
I'd prefer sending you full source files outside this thread to maintain source integrity, and we could update this thread with impending solution if any.
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2021 Xystra, Inc. All rights reserved. --> <component name="RadioGridView" extends="SGDEXComponent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://devtools.web.roku.com/schema/RokuSceneGraph.xsd" > <interface> <function name="switchMode" /> </interface> <script type="text/brightscript" uri="RadioGridView.brs" /> <script type="text/brightscript" uri="pkg:/components/AppUtils.brs" /> <script type="text/brightscript" uri="pkg:/components/SGDEX/Views/utils/Utils.brs" /> <children> <!-- Background, randomly selected --> <Poster uri="pkg:/images/background/blue.png" width="1920.0" height="1080.0" translation="[0, 0]" /> <!-- Main Audio component --> <Audio id="streamPlayer" /> <!-- Headline --> <Group> <Poster uri="pkg:/images/logo.png" width="75" height="75" translation="[50.0, 60.0]" /> <Label id="radioHeadline" translation="[135, 30]" maxLines="1" /> <Label id="radioMoto" translation="[135, 150]" horizAlign="left" /> </Group> <!-- Now Playing component --> <Group id="nowStreaming" visible="true" > <Poster uri="pkg:/images/background/nowplaying.9.png" width="801" height="300" translation="[1120.0, 100.0]" /> <Poster id="nowPlayingLogo" width="200" height="200" translation="[1200, 150]" /> <Label id="nowPlayingStation" translation="[1430.0, 140.0]" horizAlign="left" /> <Label id="nowPlayingLocation" translation="[1430.0, 180.0]" horizAlign="left" /> <Label id="nowPlayingRDSHeader" translation="[1430.0, 230.0]" horizAlign="left" /> <Label id="nowPlayingRDS" translation="[1430.0, 255.0]" horizAlign="left" width="420" wrap="false" ellipsizeOnBoundary="true" /> <Poster id="nowPlayingControl" height="75" width="75" translation="[1480.0, 290.0]" /> <Poster id="nowPlayingFavorite" height="75" width="75" translation="[1570.0, 290.0]" /> </Group> <!-- RowList of channels --> <RowList id="stationList" translation="[ 100, 400 ]" itemComponentName="stationItem" numRows="4" itemSize="[ 1720, 250 ]" rowItemSize="[ [170, 170] ]" rowItemSpacing="[ [ 50, 0 ] ]" showRowLabel="[ true ]" drawFocusFeedback="true" focusBitmapUri="pkg:/images/background/stationfocus.9.png" rowFocusAnimationStyle="floatingFocus" /> <Timer id="rdsTimer" repeat="true" duration="5" /> <!-- Aux features controls --> <Group> <Poster uri="pkg:/images/star.png" width="40.0" height="40.0" translation="[1560,10]" /> <Label id="menuLabel" translation="[1610, 15]" wrap="false" /> </Group> <Group id="busySpinner" visible="false" > <Poster uri="pkg:/images/background/modal.png" width="1920" height="1080" translation="[0.0,0.0]" /> <BusySpinner id="spinner" translation="[960, 540]" /> <Label id="busyLoading" translation="[820, 650]" /> </Group> </children> </component>
sub primeRadio() print "Starting playback: " + m.playTask.stationContent.title m.current = m.playTask.stationContent m.tgRegistry.Write("lastRadio", m.current.id) m.tgRegistry.Flush() m.nowPlayingStation.text = m.playTask.stationContent.title m.nowPlayingLocation.text = m.playTask.stationContent.location m.nowPlayingLogo.uri = "<link to png file>" m.nowPlayingRDS.text = "Not available" if m.playTask.stationContent.rds then startRDSTimer() end if favsJson = m.tgRegistry.Read("radioFavorites") favorites = ParseJson(favsJson) m.currentIsFavorite = false for each fav in favorites if fav.id = m.current.id then m.currentIsFavorite = true end if end for if m.currentIsFavorite then m.nowPlayingFavorite.uri = "pkg:/images/heart-focus.png" else m.nowPlayingFavorite.uri = "pkg:/images/heart-off.png" end if m.nowPlayingControl.uri = "pkg:/images/pause.png" m.audioPlayer.content = m.playTask.stationContent m.audioPlayer.control = "play" m.top.getScene().setFocus(true) if not m.isSubGroup then ShowSpinner(false) end if end sub function onKeyEvent(_key_ as String, _press_ as Boolean) as Boolean handled = false if _press_ then ? _key_ + " pressed." if _key_ = "down" then if not m.stationList.hasFocus() then m.stationList.setFocus(true) handled = True end if end if if _key_ = "up" then m.nowPlayingControl.setFocus(true) end if if _key_ = "left" or _key_ = "right" then if not m.stationList.hasFocus() then if m.nowPlayingControl.hasFocus() then m.nowPlayingFavorite.setFocus(true) else m.nowPlayingControl.setFocus(true) end if handled = True end if end if if _key_ = "OK" then if m.nowPlayingControl.hasFocus() then OnNowPlayingControlSelected() handled = True else if m.nowPlayingFavorite.hasFocus() then OnNowPlayingFavoriteSelected() handled = True end if end if 'keys not used in fullscreen if _key_ = "replay" or _key_ = "play" or _key_ = "rewind" or _key_ = "fastforward" then handled = true end if end if return handled end function
@RokuJonathanD any updates from the dev team?
I have a similar issue with the Video node. My channel has a main menu, on which the user can browse, and pressing the *-button brings up some additional information about the selected item. When the user selects an item to play, the Video node becomes visible and in focus, and then the user will get the built-in options menu for selection subtitles, etc. which is desired. However, when returning to the main menu, the *-button still brings up the built-in menu, rather than going to onKeyEvent as it did the first time om the main menu.
I have tried using removeChild() to remove the (hidden) video component, when returning to the main menu, just to see if that made a difference, but it did not.
I wonder if the original poster also sees the issue remain after their Audio node is done playing.
I guess that for my last question, I should have read the original post properly, as it clearly states that after Audio control is set to "stop", the onKeyEvent() handling of the *-key is restored.
I have tried the same on my Video node, and similarly see that onKeyEvent() handling resumes once the video is properly stopped. (Apparently pausing, hiding, or even disconnecting the Video node from its parent was not sufficient.)
So it seems that Audio/Video on Roku has special handling of the *-key, in that while playing these components will handle it irrespective of the ordinary focus chain. That could be considered both good and bad. Good because all Roku users have access to the same audio/subtitle/accessibility UI across all channels, even as some large brands would have liked to put their own touch on the accessibility menus.
It would be nice to get official confirmation from Roku that this is how it is designed to be. That channels cannot have custom handling of the *-key while audio or video is playing.
@devnullpointer @JesUltra I'm guessing you guys are using the new Express 4K model. I am facing the exact same issue when playing back video content as per https://community.roku.com/t5/Roku-Developer-Program/Options-key-override-not-working-on-Express-4K-...
As my exact same code works fine on other Roku models such as Ultra and Streaming Stick +, please try to test using a non-Express 4K model to see if the same thing happens with you.
My suspicion is that there's some Roku firmware bug only impacting the new Express 4K model where the video player thinks it's always on full screen even when it's not and overriding any user binding of the * options key.
FYI, overriding the * options key binding will only work if the video player is not full screen so you have to make sure to lower the player size using width & height attributes and in order to return to full screen again, set width=0 and height=0.
Before I changed my code to apply control="stop", I saw the problem of the built-in audio/accessibility menu sliding in on any press of *, after having played a video on a Roku Ultra 4670X running Roku OS 10.5.0.4208.
I am satisfied that the built-in menu appears while my video is actively playing, and that is the behavior I see now. I do not think the original poster is satisfied with that same behavior, though I suspect that it is "by design", since all the major channels bear with it.
My issue is more towards the Audio tag. When playing video the *-key works like I expect it to. When the Video height/width is set to fullscreen I expect the tv settings to show, when exiting fullscreen to a mini player style height/width I regain access to the *-key.
When playing audio streams, I was hoping for the same functionality as a "mini video" gives me. But for now I need to "stop" the audio stream to regain control of the *-key
@devnullpointer wrote:When playing video the *-key works like I expect it to. When the Video height/width is set to fullscreen I expect the tv settings to show, when exiting fullscreen to a mini player style height/width I regain access to the *-key.
This is the current behaviour when playing videos except for Express 4K model 3940 series users which does not allow access to the * key during playback, even when using mini player. It appears that this will have to be fixed in a future Roku firmware update.
Interestingly enough, the video component has an undocumented allowOptionsKeyOverride boolean parameter. However, even when setting it to true, options key override still does not work on the Express 4K during non-fullscreen video playback.
@devnullpointer wrote:When playing audio streams, I was hoping for the same functionality as a "mini video" gives me. But for now I need to "stop" the audio stream to regain control of the *-key
Even though you are not playing a video, did you try putting values for width and height? Also, try setting allowOptionsKeyOverride to true to see if it makes a difference.