Make roVideoScreen loop forever

Hi all,
I am new to Roku development. I have a project where we are using a Roku to loop through a series of videos on a TV. The playlist is retrieved via REST API and then the looping starts.

In my code, what I really want to do is just load a video player, then have it play one video after the next. However, there does not seem to be a way to have the player play another video when it finishes. As written it exits before playing the next one.


Function startVideo()

    p = CreateObject("roMessagePort")
    videoScreen = CreateObject("roVideoScreen")
    videoScreen.setMessagePort(p)
    videoScreen.show()

    while true
        print "Refreshing video list..."
        playlist = CreateObject("roArray", 10, true)  
        mediaInfo = getMediaInfoForProject("2246141")
        for each media in mediaInfo
                'media.id
                'media.name
                'media.desc
                'media.type
                'media.thumb
                videoURL = getVideoForID(Stri(media.id).Trim())
                media.videoURL = videoURL
                playlist.push(media)
        end for

        for each media in playlist
            print "next video is ";media.name
            videoclip = CreateObject("roAssociativeArray")
            videoclip.StreamBitrates = [0]          ' 0 = no dots, adaptive bitrate  
            videoclip.StreamUrls = [media.videoURL]
            videoclip.StreamQualities = ["HD"]
            videoclip.StreamFormat = "mp4"
            videoclip.Title = "" ' this is what is shown when the video is loading
    
            videoScreen.SetContent(videoclip)

            while true
                msg = wait(0, videoScreen.GetMessagePort())
                if type(msg) = "roVideoScreenEvent"
                    if msg.isScreenClosed() then 'ScreenClosed event
                        print "Screen closed, Completing video"
                        exit while
                    else if msg.isFullResult()
                      print "playback completed"
                      exit while
                    else if msg.isStreamStarted()
                        print "playback started"
                    else if msg.isRequestFailed()
                        print "play failed: "; msg.GetMessage()
                    else if msg.isStatusMessage()
                        print "status="; msg.GetMessage();" type=" msg.GetType()
                    else if msg.GetType() = 15
                        print "Interrupted by user hitting a button on the remote"
                    else
                        print "Unknown event: "; msg.GetType(); " msg: "; msg.GetMessage()
                    endif
                end if
            end while

            print "One done, what's next?"
        end for
    end while
End Function

What I see in the debug console is this:

Refreshing video list…
next video is video4
playback started
playback completed
One done, what’s next?
next video is video2

But video2 never plays, and it returns to the home screen. Help?

I’m not sure you can do that with roVideoScreen. You may have to create a new roVideoScreen object (and port) for each item in your content loop – or use roVideoPlayer with SetContentList().

Yeah, I think you are right. I just made a black screen and pushed that on the stack, then iteratively push a video player on the stack for each video. This seems to work ok for now.

Came up with a solution that works pretty well.

I use a black screen as the base of the screen stack:

black=&h000000
screen0=CreateObject("roScreen")
screen0.Clear(black)
screen0.finish()

Then I use a roVideoPlayer with the playlist (thanks belltown!), and refresh the player at the end of the playlist:

Function startVideoInPlayer()
    
    p = CreateObject("roMessagePort")
    while true
        playlist = getCurrentPlayList()
    
        videoPlayer = CreateObject("roVideoPlayer")
        videoPlayer.setMessagePort(p)

        contentList = []
        for each media in playlist
          contentList.Push({ Stream: { url: media.videoURL }, StreamFormat: "mp4"})
        end for
        videoPlayer.SetContentList(contentList)
        videoPlayer.Play()
        while true
            msg = wait(0, p)
            if msg <> invalid
                'print "message";msg
                if msg.isFullResult()
                    print "playback completed"
                    exit while
                end if
            end if
        end while
    end while

End Function

Hope this helps someone in the future.

I’m glad you got it working. However, it might be better to use an roImageCanvas for your black facade screen. It’s not recommended to mix 2D API components (roScreen) and standard components – even though it may work if you understand what’s going on – since the 2D API display stack is maintained independently from the main screen component display stack (see here).

Here’s what I would do:


imageCanvas = CreateObject ("roImageCanvas")
imageCanvas.SetLayer (0, {Color: "#000000"})
imageCanvas.Show ()

and, of course, call imageCanvas.Close () when you’ve finished displaying your videos.

Thanks for the hint, I have made the switch to a roImageCanvas for my black facade.