Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Helaman
Channel Surfer

roVideoPlayer SetContentList function not working

This may seem like a super basic question, but I just can't figure it out! 😂

One the app I am creating I am using a basic Video xml element to play a given video, however I need to be able to check to see if I get a 404 when trying to play a video. The problem lies in the fact that the Video object will just repeatedly request a video from my server even if it only gets 404s back.

So, I decided to swap to a `roVideoPlayer` object instead since it gives me more control and can hopefully tell me what the response code of the given video is, that way I can have the player stop playing and display an error message if it gets a 404. The problem is that I just CAN NOT get the `SetContentList` function working! No matter how many different combinations of arrays, associative arrays, etc. I try, it just tells me that "Interface not a member of BrightScript Component". I've checked the 3+ sources of documentation and scoured the forum, but I just can't figure it out. As far as I know, it's supposed to be an array of `roAssociativeArray`s, and each associative array contains the details of a video to be played.

My code has been multiple different variations of this, but never works:

```video = { Title: "Video Title", Stream: { url: videoUrl }, StreamFormat: "mp4" } videoPlayer.SetContentList([video])```

Alternatively, if there is a way to check if a Video SceneGraph element fails to play a video due to a 404 error being returned from the server, that would solve the original problem.

 

Thank you for your help 🙂

0 Kudos
9 REPLIES 9
renojim
Community Streaming Expert

Re: roVideoPlayer SetContentList function not working

Is there a reason why you're using SetContentList and not just SetContent?

For a video node, do you have an observer on the "state" of the video node?  It should fire on any error.

Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
Helaman
Channel Surfer

Re: roVideoPlayer SetContentList function not working

SetContentList is the function mentioned in the documentation, although I have tried SetContent. In terms of observing the state of the Video player, I can observe that it is buffering, playing, paused, etc. my problem is that I can't detect if its getting a 404 when trying to buffer a non-existent video.

Thank you for help btw

0 Kudos
renojim
Community Streaming Expert

Re: roVideoPlayer SetContentList function not working

I don't know why your "state" observer isn't working.  I tried setting the URL to a nonexistent video on my server and my server returned a 404, my "state" observer fired, GetData() returned "error". and my video node "errorCode" was set to 404.

Edit:  "errorCode" is set to -1.  "errorStr" shows the 404.

Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
Helaman
Channel Surfer

Re: roVideoPlayer SetContentList function not working

Is that for a `roVideoPlayer` object or a `roSGNode` that represents a Video SceneGraph element? I have a "state" observer on the `roSGNode` for my video element, but it doesn't fire with errors, it just fires for states like "buffering", "paused", "playing", etc.

0 Kudos
renojim
Community Streaming Expert

Re: roVideoPlayer SetContentList function not working

That's for a Video node.  My "onState" observer function fires first with "buffering" and then with "error" when I set the URL to a nonexistent file.  I've also used observers with message ports and waited on the port in the main thread.  That looks something like this:

Function displayVideo(video as Object) as Integer
    print "Displaying video: "; video["url"]

    vn = m.video_node
    vc = createObject("roSGNode", "ContentNode")
    vc.url = video.url
    vc.StreamFormat = video.StreamFormat
    print vn.observeField("position", m.port)
    print vn.observeField("control", m.port)
    print vn.observeField("state", m.port)

    vn.content = vc
    vn.setFocus(true)
    vn.control = "play"
    while true
        msg = wait(0,m.port)
        msgtype = type(msg)
        print msgtype
        if msgtype = "roSGNodeEvent" then
            node = msg.GetNode()
            field = msg.GetField()
            data = msg.GetData()
            print node, field, data
            if field = "position" then
                position = data
            else if field = "control" and data = "stop" then
                exit while
            else if field = "state" then
                if data = "finished" then
                    exit while
                else if data = "buffering" then
                    m.video_screen.visible = true
                else if data = "error" then
                    print vn.errorCode
                    print vn.errorMsg
                    print vn.errorStr
                    print vn.errorInfo
                else if data = "playing" then
                   '
                else if data = "paused" then
                   '
                end if
            end if
        else if msgtype = "roSGScreenEvent" then
            print msgtype, msg.GetData(), msg.isScreenClosed()
            vn.control = "stop"
            exit while
        end if
    end while
    vn.control = "stop"
    print vn.unobserveField("position")
    print vn.unobserveField("control")
    print vn.unobserveField("state")
    return position
End Function

 
and produces this output:

roSGNodeEvent
video           control         play
roSGNodeEvent
video           state           buffering
roSGNodeEvent
video           state           error
errorCode:  -1
errorMsg:  There was an error in the HTTP response.  This could mean that malformed HTTP headers or an HTTP error code was returned.
errorStr:  reader pick stream error:HTTP error:HTTP server returned error code:404:extra:etype:buffer
errorInfo:  <Component: roAssociativeArray> =
{
    category: "http"
    clipid: 1
    dbgmsg: "reader pick stream error:HTTP error:HTTP server returned error code:404:extra:etype:buffer"
    drmerrcode: 0
    errcode: 2
    ignored: false
    source: "buffer:reader"
}
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
Helaman
Channel Surfer

Re: roVideoPlayer SetContentList function not working

Wow, I didn't realize you could observe a field and then have it go to a port instead of a function... I still have a lot to learn about Roku app development 😂 So that works if I give the player a non-existent video to begin with, but say (and this is the issue I'm trying to resolve) that the video exists originally and then gets deleted while it's being played. That's when I can't detect that it's getting an error, it just thinks it's buffering.

However, I did find a workaround; every time the player starts buffering, I send a GET request to the same url and look at the response and then act accordingly. That way I can tell if the video stopped existing during playback. Really weird issue, I know.

I still wish I could get the `roVideoPlayer` working though, because the documentation says that when given a list of videos a `roVideoPlayer` will automatically pre-buffer the next video to make playback of a bunch of videos seamless. That would help me a lot, instead of taking videos and concatenating them on the server and then returning the result to the device. (I'm trying to basically show a bunch of ~15 second videos in a row on a TV seamlessly, almost like a slideshow).

Anyways, thank you @renojim SO much for helping out!

0 Kudos
renojim
Community Streaming Expert

Re: roVideoPlayer SetContentList function not working

I don't know how much time you want to spend on roVideoPlayer.  When I just tried to use it I got, "BRIGHTSCRIPT: WARNING: roVideoPlayer: This component is deprecated".  I don't see that mentioned in the documentation for roVideoPlayer, but it is mentioned here.  If you want to experiment, this works for me:

 player = CreateObject("roVideoPlayer")
 player.SetContentList([{
     Stream: { url: "http://192.168.0.118/1.mp4" }
     StreamFormat: "mp4"
 },{
     Stream: { url: "http://192.168.0.118/2.mp4" }
     StreamFormat: "mp4"
 },{
     Stream: { url: "http://192.168.0.118/3.mp4" }
     StreamFormat: "mp4"
 },{
     Stream: { url: "http://192.168.0.118/4.mp4" }
     StreamFormat: "mp4"
 },{
     Stream: { url: "http://192.168.0.118/5.mp4" }
     StreamFormat: "mp4"
 }])
 player.SetMessagePort(m.port)
 player.SetLoop(true)
 player.SetPositionNotificationPeriod(1)

 player.Play()
 while true
     msg = wait(0, m.port)
     if msg <> invalid then
         print type(msg),msg.GetType(); ","; msg.GetIndex(); ": "; msg.GetMessage()
     end if
 end while

 

Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
RokuKC
Roku Employee
Roku Employee

Re: roVideoPlayer SetContentList function not working

Roku SceneGraph is the recommended development platform, and there the Video node should be used.

https://developer.roku.com/docs/developer-program/core-concepts/core-concepts.md

https://developer.roku.com/docs/developer-program/core-concepts/playing-videos.md

Otherwise, as far as I know, roVideoPlayer is still supported for roScreen / 2D UI only. 
(The deprecation notice has been there for many many years, but I believe it does not apply in that limited/unusual situation, but rather was intended to guide streaming channel developers to transition to SceneGraph.)

 

Helaman
Channel Surfer

Re: roVideoPlayer SetContentList function not working

Thank you for your help! As it turns out, I actually was doing it correctly, but I had to create the `roVideoPlayer` on the main thread, which was what was causing me my problems.

0 Kudos