Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
pablogott
Level 7

Play All using videoplayer sample

My channel is based on the video player sample.

I'd like a category to have a play all button, but I'm struggling with brightscript in general.

My understanding is roVideoscreen won't work, as that won't play a playlist.

I also can't figure out how to grab all the videos from my xml and play them as a a playlist, or how to make a special button that launches a player. Any help would be much appreciated!
0 Kudos
6 Replies
Roku Employee
Roku Employee

Re: Play All using videoplayer sample

videoplayer uses this syntax for handling the list of videos: showlist[showindex]

so showlist would probably contain all the videos that you might want to put in a playlist.

So if you add a function that you call instead of the video playback function and modify the video playback function something like this:

Note: I did some testing and modified this to make it work better.


function PlayAllvideos(showlist,showindex)
result=""
while true
?"show index=";showindex
result=ShowVideoScreen(showlist[showindex])
print "result=";result
if result="user cancelled playback" then
return result
end if
showindex=showindex+1
end while
end function

Function showVideoScreen(episode As Object) as string

if type(episode) <> "roAssociativeArray" then
print "invalid data passed to showVideoScreen"
return -1
endif

port = CreateObject("roMessagePort")
screen = CreateObject("roVideoScreen")
screen.SetMessagePort(port)

screen.SetPositionNotificationPeriod(30)

if episode.streamformat="hls" then
di=createobject("roDeviceInfo")
if di.getDisplayType()="HDTV" then
episode.StreamQualities = ["HD"]
else
episode.StreamQualities = ["SD"]
end if
end if
screen.SetContent(episode)
screen.Show()


while true
msg = wait(0, port)

if type(msg) = "roVideoScreenEvent" then
print " msg = "; msg.getMessage() " | index = "; msg.GetIndex()
if msg.getmessage()="Playback interrupted by user." then
return "user cancelled playback"
end if
if msg.isScreenClosed()
return ""
else if msg.isRequestFailed()
return "video playback failed"
else if msg.isStatusMessage()
print "Video status: "; msg.GetIndex(); " " msg.GetData()
else if msg.isButtonPressed()
print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
else if msg.isPlaybackPosition() then
nowpos = msg.GetIndex()
RegWrite(episode.ContentId, nowpos.toStr())
end if
end if
end while

End Function


You would also have to modify refreshShowDetailScreen to add a Play All button:

   if validateParam(screen, "roSpringboardScreen", "refreshShowDetail") = false return -1
if validateParam(showList, "roArray", "refreshShowDetail") = false return -1

show = showList[showIndex]
screen.ClearButtons()
if regread(show.contentid) <> invalid and regread(show.contentid).toint() >=30 then
screen.AddButton(1, "Resume playing")
screen.AddButton(2, "Play")
else
screen.addbutton(2,"Play")
end if
if showlist.count() > 1 then
screen.addbutton(3,"Play All")
end if
screen.SetContent(show)
screen.Show()


and the showDetailScreen function you have to handel when button 3 is pressed:


if msg.GetIndex() = 3
playAllVideos(showlist,showindex)
endif
0 Kudos
pablogott
Level 7

Re: Play All using videoplayer sample

Thank you so much. This is amazing.

So this adds a play all button on an episode level page?
0 Kudos
pablogott
Level 7

Re: Play All using videoplayer sample

This is fantastic. Works great. Thank you very much!
0 Kudos
pablogott
Level 7

Re: Play All using videoplayer sample

2 issues, in case anyone else wants to use this.

1) Play All is an option for the last episode, which is unnecessary as it doesn't (and probably shouldn't) loop.

I think the trick is in here:
 
if showlist.count() > 1 then
screen.addbutton(3,"Play All")
end if


2) Once the last episode is finished, the channel needs to be restarted before anything else can be played again. I'm still looking for clues on that one.
0 Kudos
dcringo
Level 7

Re: Play All using videoplayer sample

I am trying to implement this code, but I am having an issue with the "playback interrupted by user." situation.

When I use the code as written in the example, if the playback is interrupted, I get a "type mismatch" here:

if type(event) = "roVideoScreenEvent" then
if event.getmessage()= "Playback interrupted by user." then

return "user cancelled playback"
end if


It breaks on the return. I am sort of a noob on the rules of a function returning things, so originally I rewrote my app to avoid having to do this. That resulted in, you guessed it, a recursive situation that caused a stack overflow after about 30 videos.

If I can figure out how to handle this last item, i will have a "play all" function that actually even loops the playlist over and over.

Any help would be appreciated
0 Kudos
dcringo
Level 7

Re: Play All using videoplayer sample

Well, I feel like a great big idiot.

I was telling my showVideoPlayerScreen function to return an Integer instead of a String, which is why I got the type mismatch.

I am going to post my working code here just in case anyone else would like to use this functionality but has a similar type of video array to mine. (the basic idea of the code came right from RokuJoel's example, but because I am pulling my video info from an API call, I had to do a lot of modification, plus I added a feature to make it loop back to the beginning when the last one plays)

Function getNewVidInfo(items, passIndex, pageTitle = invalid, parentPageTitle = invalid)

result = ""
while true

if(RegRead(PlayStartVariableName) <> invalid)
RegDelete(PlayStartVariableName)
'print "the regRead if statement was triggered"
end if
if (passIndex = items.count())
passIndex = 0
end if

index = passIndex

feedUrl = "/asset?id=" + tostr(items[index].ContentId) + "&fields=hls_url,closed_caption_urls,rating,duration,time_start,date,trick_mode_urls"
conn = InitFeedConnection(feedUrl)
response = conn.LoadFeed()
if response = invalid
return -1
end if

video = convertDvidsApiAssetResponse(response,items[index])

video.PlayStart = video.TimeStart
result = showVideoPlayerScreenAll(items, passIndex, video, pageTitle, invalid)

if result = "user cancelled" then
return result
end if

passIndex = passIndex +1
end while
End Function



Function showVideoPlayerScreenAll(items, passIndex, video As Object, pageTitle = invalid, parentPageTitle = invalid) As String

if type(video) <> "roAssociativeArray" then
print "invalid data passed to showVideoPlayerScreen"
return -1
end if
port = CreateObject("roMessagePort")
screen = CreateObject("roVideoScreen")
screen.setMessagePort(port)

if(video.ContentId <> invalid)
PlayStartVariableName = right(video.ContentId,6)+"pos" ' remove video- from contentid
screen.SetPositionNotificationPeriod(5)
end if
screenName = "asset_watch/" + right(video.ContentId,6)
screen.SetContent(video)
setBreadCrumbs(screen, pageTitle, parentPageTitle)
screen.Show()

while true
msg = wait(0, port)

if type(msg) = "roVideoScreenEvent" then
if msg.getmessage()= "Playback interrupted by user." then
return "user cancelled"
end if

if msg.isScreenClosed()
'print "Screen closed"
return ""
else if msg.isRequestFailed()
'print "Video request failure: "; msg.GetIndex(); " " msg.GetData()
else if msg.isStatusMessage()
'print "Video status: "; msg.GetIndex(); " " msg.GetData()
else if msg.isButtonPressed()
'print "Button pressed: "; event.GetIndex(); " " event.GetData()
else if msg.isPlaybackPosition() then
currentPosition = msg.GetIndex()
' If we're less than 10 seconds from the end of the video go ahead and delete the position tracker
if(currentPosition + 10 > video.length and RegRead(PlayStartVariableName) <> invalid)
RegDelete(PlayStartVariableName)
else
'print "CurrentPosition";currentPosition
RegWrite(PlayStartVariableName, currentPosition.toStr())
end if
end if
end if
end while


End Function
0 Kudos