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: 
scyber
Visitor

Transcoding and HLS rebuffering

I have a transcoding server that is converting video feeds into HLS files. Playback is working, however at times the playback will rebuffer and "skip" back a number of seconds. It appears that if the transcoding server is not fast enough to transcode in real-time, the Roku will reach the end of m3u8 file and then skip back to the beginning of its buffer. Depending on the speed of the server, one rebuffer is sometimes enough to play through till the end of the video.

If my diagnosis of the behavior is correct, is there an event I can catch to simply pause the video when it runs out of video? Pausing would at least been a preferred behavior to "skipping" back.
0 Kudos
9 REPLIES 9
TheEndless
Channel Surfer

Re: Transcoding and HLS rebuffering

I'm not positive if this would work, but it seems like it should... You could potentially capture the isStatusMessage() and isPlaybackPosition() events (with a notification period of 1 second). Then, if isStatusMessage is a rebuffer, pause for whatever timeframe you want, then Seek() to the last playback position before resuming. You might get a little skip back, but it would be less than a second, rather than what I would assume is probably a good bit more than that now.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
RokuMarkn
Visitor

Re: Transcoding and HLS rebuffering

Each segment in an HLS stream is a transport stream, and it's not possible to seek within a transport stream. So the seek granularity in an HLS stream is 10 seconds (or whatever the segment duration is). You can't seek with finer resolution than that. (This is not much different than MP4 files, in which you can only seek to the resolution provided by the I-frames in the stream.)

I doubt that you'll be able to pause at the rebuffer as you're suggesting. When you receive the rebuffer status message, the stream has already stopped playing and the pause isn't going to do anything, I think. You might try adjusting your server to transcode more segments initially, before it starts playing.

--Mark
0 Kudos
TheEndless
Channel Surfer

Re: Transcoding and HLS rebuffering

"RokuMarkn" wrote:
Each segment in an HLS stream is a transport stream, and it's not possible to seek within a transport stream. So the seek granularity in an HLS stream is 10 seconds (or whatever the segment duration is). You can't seek with finer resolution than that. (This is not much different than MP4 files, in which you can only seek to the resolution provided by the I-frames in the stream.)

How does the PlayStart property work, then? I assumed it just performed a seek based on the M3U8 segment duration and offset. I'm using that in one of my channels to resume playback of an HLS stream... though those M3U8 files contain every segment for DVR purposes, so maybe it's only chance that it works in my case.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
RokuMarkn
Visitor

Re: Transcoding and HLS rebuffering

I'm not sure I quite understand the question -- let me rephrase what I said. You can seek to any TS file that's in the m3u8, but you can't seek anywhere in a TS file except to the beginning of it. So if your TS files are 10 seconds long and they're all listed in the m3u8, you can seek to location 0, location 10s, location 20s, etc. but you couldn't seek to 15s since that's not the start of a TS file.

--Mark
0 Kudos
TheEndless
Channel Surfer

Re: Transcoding and HLS rebuffering

"RokuMarkn" wrote:
I'm not sure I quite understand the question -- let me rephrase what I said. You can seek to any TS file that's in the m3u8, but you can't seek anywhere in a TS file except to the beginning of it. So if your TS files are 10 seconds long and they're all listed in the m3u8, you can seek to location 0, location 10s, location 20s, etc. but you couldn't seek to 15s since that's not the start of a TS file.

--Mark

To resume playback in my channel, I'm setting the PlayStart content metadata to the last playback position. I haven't tested it that closely, so it could be resuming at the 10 second boundary (i.e. internally changing 15 to 10), but it seems to work. I assumed the video player just did a Seek() to the specified PlayStart value (find file at PlayStart / SegmentDuration, then Seek in that file to PlayStart % SegmentDuration), which is also why I thought my suggestion above would work. If you can only seek to the segment boundary, then nevermind 😛
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
kbenson
Visitor

Re: Transcoding and HLS rebuffering

"RokuMarkn" wrote:
Each segment in an HLS stream is a transport stream, and it's not possible to seek within a transport stream. So the seek granularity in an HLS stream is 10 seconds (or whatever the segment duration is). You can't seek with finer resolution than that. (This is not much different than MP4 files, in which you can only seek to the resolution provided by the I-frames in the stream.)

I doubt that you'll be able to pause at the rebuffer as you're suggesting. When you receive the rebuffer status message, the stream has already stopped playing and the pause isn't going to do anything, I think. You might try adjusting your server to transcode more segments initially, before it starts playing.

--Mark


Theoretically you could be checking the m3u8 file to see if the current segment is the last listed (but not the end) and pause at or before the end of the segment until a few more segments have been added, right? That would get the pause while rebuffering behavior he's asking for, and I imagine you could even use an overlay to display a rebuffering message.
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
retrotom
Visitor

Re: Transcoding and HLS rebuffering

"scyber" wrote:
I have a transcoding server that is converting video feeds into HLS files. Playback is working, however at times the playback will rebuffer and "skip" back a number of seconds. It appears that if the transcoding server is not fast enough to transcode in real-time, the Roku will reach the end of m3u8 file and then skip back to the beginning of its buffer. Depending on the speed of the server, one rebuffer is sometimes enough to play through till the end of the video.

If my diagnosis of the behavior is correct, is there an event I can catch to simply pause the video when it runs out of video? Pausing would at least been a preferred behavior to "skipping" back.


I've had the same issue as you and what we've decided to do in Gabby is implement a "communication framework" in conjunction with streaming the media. That makes the application, etc. more "chatty", but helps handle this issue fairly well. Doing this gives you a lot of power over how you respond to and detect buffer underuns. If you can't stop the buffer underrun, you should at least handle it gracefully. So one thing we do is ask for "buffer" status before playback begins. Because you should know how many segments have been transcoded, it makes this easy to do. So first, you keep asking the transcoding server how many segments are ready until you fill a buffer -- then you begin playback. The second thing you can do is keep track of how long it took to fill the buffer (from the roku side). We're still playing with this, but if it takes you more than 60-70 seconds to fill 60 seconds of video -- you KNOW you can't keep up with playback. Lastly, you can send the same request everytime the roku hits its HLS target duration (using streamposition). Based on that status message, you should be able to detect upcoming buffer underruns. For instance -- if your buffer is 6 segments...and the status message drops to 4 segments available (or maybe even 3)...then you probably want to pause or warn the user with some kind of visual overlay. We're thinking about using a flashing yellow warning to let them know that "hey...your computer can't keep up". I wouldn't freak out if the value dropped to 5 because sometimes key frames don't arrive in a tight enough duration -- so anything less than 75% fill rate is my cutoff. To clarify, when I say "buffer" -- I mean minimum number of segments available for immediate playback.

Hopefully that helps,
RT
0 Kudos
kbenson
Visitor

Re: Transcoding and HLS rebuffering

"retrotom" wrote:
So first, you keep asking the transcoding server how many segments are ready until you fill a buffer -- then you begin playback. The second thing you can do is keep track of how long it took to fill the buffer (from the roku side). We're still playing with this, but if it takes you more than 60-70 seconds to fill 60 seconds of video -- you KNOW you can't keep up with playback. Lastly, you can send the same request everytime the roku hits its HLS target duration (using streamposition). Based on that status message, you should be able to detect upcoming buffer underruns. For instance -- if your buffer is 6 segments...and the status message drops to 4 segments available (or maybe even 3)...then you probably want to pause or warn the user with some kind of visual overlay. We're thinking about using a flashing yellow warning to let them know that "hey...your computer can't keep up". I wouldn't freak out if the value dropped to 5 because sometimes key frames don't arrive in a tight enough duration -- so anything less than 75% fill rate is my cutoff. To clarify, when I say "buffer" -- I mean minimum number of segments available for immediate playback.


I think I just said that, but without all the actual experience and details... 😉

It would be nice if this was supported natively in the HLS implementation on the Roku. The ability to specify a minimum (for paused buffering) and maximum (for resume) required future segments would be useful. Can we get any info from Roku on whether they have planned updates to HLS playback to allow more developer control over the experience?
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
renojim
Community Streaming Expert

Re: Transcoding and HLS rebuffering

Here's something I just discovered that is kind of off-topic, but related. I've been playing with the PlayOn channel and I have the issue that both my internet connection and my processor may not be up to the task, so what I do is start a stream and then press pause. When you do this, you'll notice that both ends of the pause bar say 0, but if you press the down arrow the pause bar will be updated and once it gets to a few minutes remaining (the number on the right), I'll start to play the program. It works pretty well for me, but I've noticed that trying to seek within the stream doesn't really work. In fact, I can rewind a minute or two and once the stream starts playing again its quite possible that it will pickup after the point where I pressed rewind. It usually takes several tries to get it to start playing from the point I want. Has anyone else noticed this?

-JT
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
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.