Order Now AdSolution Sign Up | Login » Bits on the Run Sign Up | Login »

Forums

/

Dynamic Streaming - block moving up quality levels?

13 replies [Last post]
Reply

Hi all

I apologise in advance for the long post.

We are using v5.8.2011 (licenced), with rtmp streaming from Amazon Cloudfront. We embed, create playlists and set up levels with the Javascript API.

A playlist contains maybe 5-10 .mp4 files, maybe 20 seconds each, with 7 quality levels for each file ranging from 40kb/s to 3mb/s.

My questions are:

1) When creating the levels, does it make a difference whether we put the highest quality first or last?
This page suggests putting the best first...
http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12535/video-delivery-rtmp-stre...
This page has examples putting the lowest first...
http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/15995/jw-embedder-reference-gu...

2) Is it possible to force dynamic streaming to only switch towards the lower quality levels, i.e once it has failed at a level to never go back up there?

3) If not, is it possible to override the default blacklist time so that we can make it so long that effectively the higher levels don't come back into play?

4) Is there a way to carry forward the Level between one playlist item and the next?

5) If these are not possible, could they be added as feature request? Or is it something that can only be done server side?

6) I've seen in ticket #1020 you refer to a proposed setLevel() method which "initiates a bitrate switch to the assigned level" where "the player will remain at the given bitrate level for the remainder of the video playback session". Would it be possible to create a setMaximumLevel(level:Number,scope:String), which would set the Maximum allowed level and could be set to apply either to only the current playlist item or to the whole playlist? With the other proposals in that ticket we could then do something like:

onLevel(setMaximumLevel(getCurrentLevel(),'playlist')) or onLevel(setMaximumLevel(getCurrentLevel(),'item'))

The reason for wanting to do these is to gain from Dynamic Streaming's ability to assess system performance through measuring the dropped frames.

With the increasing use of smartphones and laptops vs desktops we are concerned that although people may have sufficient bandwidth, increasingly it is the system (CPU/RAM whatever) performance that is the bottleneck.

It seems that Dynamic Streaming is prioritising the measurement of bandwidth over dropped frames. We are seeing that when a user has sufficient bandwidth, but has been switched down levels due to frames being dropped, as soon as the higher levels get un-blacklisted, he is switched back up again. This puts him in a constant loop of of jerky video while dropping down levels one at a time, then being put back to the highest levels.

Also it seems that on changing a playlist item, a brand new assessment is made, again causing him to start back at the higher quality levels again.

We think it would be better that if switch is made down a quality level due to dropped frames rather than bandwidth, then it should not be allowed to switch back up as realistically whereas bandwidth can fluctuate significantly over a video session, system performance is unlikely to vary significantly.

We would prefer to have a situation where these users get to a point where playback is smooth. We accept thought that there is a negative effect, where users that DO have sufficient CPU and whose bandwidth improves during playback, won't get moved to the higher quality levels.

To us, this is preferable to the current situation where people with low powerered systems can suffer from jerky playback until they reach a suitable low quality level, and due to repeatedly being put back to the higher levels.

If you got this far, sorry again that it was so long, and thanks for taking the time to read my post even if you can't help.

David

Reply

Hi, David -

No problem about the long post.

My questions are:

1) When creating the levels, does it make a difference whether we put the highest quality first or last?

The player will automatically sort the bitrate levels and will select the highest quality available that fits in the player window and whose bitrate is below the reported bandwidth on the client.

2) Is it possible to force dynamic streaming to only switch towards the lower quality levels, i.e once it has failed at a level to never go back up there?

In the current implementation, quality levels are blacklisted for 30 seconds, and then allowed to return. This behavior is hardcoded into the player, so to work around it would require code customization.

3) If not, is it possible to override the default blacklist time so that we can make it so long that effectively the higher levels don't come back into play?

See above.

4) Is there a way to carry forward the Level between one playlist item and the next?

The exact level won't carry over, since the levels for two items may not line up at all. The user's reported bandwidth is saved however, and used to select the next item's level.

5) If these are not possible, could they be added as feature request? Or is it something that can only be done server side?

RTMP dynamic streaming is a purely client-side implementation, so there's not much you can do server-side.

6) I've seen in ticket #1020 you refer to a proposed setLevel() method which "initiates a bitrate switch to the assigned level" where "the player will remain at the given bitrate level for the remainder of the video playback session". Would it be possible to create a setMaximumLevel(level:Number,scope:String), which would set the Maximum allowed level and could be set to apply either to only the current playlist item or to the whole playlist? With the other proposals in that ticket we could then do something like:

onLevel(setMaximumLevel(getCurrentLevel(),'playlist')) or onLevel(setMaximumLevel(getCurrentLevel(),'item'))

I think this would be better done as a player customization, where you modify the logic of the RTMP media provider. Otherwise, the bitrate switching logic, which is already quite complicated, might become even more unwieldy.

The reason for wanting to do these is to gain from Dynamic Streaming's ability to assess system performance through measuring the dropped frames.

Dynamic streaming isn't required to access dropped frames info from Flash. You can access that data directly from the NetStream object. Again, for what you're trying to do, I think you'll be better off doing some code customization.

With the increasing use of smartphones and laptops vs desktops we are concerned that although people may have sufficient bandwidth, increasingly it is the system (CPU/RAM whatever) performance that is the bottleneck.

It seems that Dynamic Streaming is prioritising the measurement of bandwidth over dropped frames. We are seeing that when a user has sufficient bandwidth, but has been switched down levels due to frames being dropped, as soon as the higher levels get un-blacklisted, he is switched back up again. This puts him in a constant loop of of jerky video while dropping down levels one at a time, then being put back to the highest levels.

Yes, the player's dropped frames heuristic isn't as sensitive as the bandwidth one. This is because factors other than pure computing power can lead to dropped frames. For example, an otherwise capable system may become momentarily bogged down by a crashing application or any other number of factors.

Also it seems that on changing a playlist item, a brand new assessment is made, again causing him to start back at the higher quality levels again.

We think it would be better that if switch is made down a quality level due to dropped frames rather than bandwidth, then it should not be allowed to switch back up as realistically whereas bandwidth can fluctuate significantly over a video session, system performance is unlikely to vary significantly.

Again, you're making assumptions about why the dropped frames occurred.

We would prefer to have a situation where these users get to a point where playback is smooth. We accept thought that there is a negative effect, where users that DO have sufficient CPU and whose bandwidth improves during playback, won't get moved to the higher quality levels.

To us, this is preferable to the current situation where people with low powerered systems can suffer from jerky playback until they reach a suitable low quality level, and due to repeatedly being put back to the higher levels.

In that case, feel free to customize the code! Since none of this stuff is standardized, we've had to make judgements as to what the optimal experience should be in terms of dynamic streaming, but if you'd like to take a stab at it, the player's source code is available on our developer site.

Good luck!

Reply

Hi Pablo

Thanks for your detailed reply.

I wasn't aware that we could make our own customizations of the code.

I don't have any experience with ActionScript, but maybe I can take a look at it sometime.

The easiest workaround for us would be to vastly increase the Blacklist time.

Do you know in which file or the source code this variable's value is currently being set to 30 seconds?

Also if I wanted to try to create code so that the blacklist can be changed using javascript, could you point me towards where I can find one example in the source such as the setVolume function that I could work from.

Thanks again

David

Reply

@David -

You can download the player source here:

http://developer.longtailvideo.com/trac/browser/trunk/fl5/

The RTMP blacklisting logic can be found here:

http://developer.longtailvideo.com/trac/browser/trunk/fl5/src/com/longtailvideo/jwplayer/media/RTMPM...

You can look at the player's JavaScript API code for an example of how Flash can be made to interact with JavaScript:

http://developer.longtailvideo.com/trac/browser/trunk/fl5/src/com/longtailvideo/jwplayer/player/Java...

(Basically, you just need to look up how the ExternalInterface call works).

Reply

Thanks Pablo

Reply

Hi

We have since discovered that a significant portion of the poor playback experience that people have been reporting to us has been down to the fact that we have been using the parameter wmode = transparent so that we can display a spinning loading GIF (which we set as a background image to a container DIV) while the jwplayer SWF is loading.

We'd now like to use wmode = direct, for the greatly improvement playback, but would like to put something in place so that users with slow bandwith are aware that the SWF is still being loaded.

Do you know of anything we can do? I've posted a topic about the things we've tried so far here...
http://www.longtailvideo.com/support/forums/jw-player/setup-issues-and-embedding/25361/show-loadingp...

Thanks again.

David

Reply

@David -

You can set wmode in your jwplayer().setup() call:

jwplayer('player').setup({
...
wmode: 'direct',
...
});
Reply

Hi Pablo

Sorry, I should have been more clear.

I know how to set the wmode, and would like to use "direct", but this means that people on slow bandwidths are staring at a blank screen for ages now, because the spinning loading GIF we set as the background can no longer be seen, if we don't use "transparent" any more.

I trying to ask if you know any way we can "put something in place so that users with slow bandwith are aware that the SWF is still being loaded."

I've posted the question in its own topic though (linked above).

Thanks

David

Reply

@David -

I understand your question now. I don't know of a great way to do this. One thing you could try is to hide the SWF while it's loading, and show it on the onReady() event, but this may cause some stability problems in the player. Another thing you could try is to set up the player with small dimensions (5px x 5px for example) and then resize the player when it's ready. That way, your animated gif will remain visible while the player is loading.

Keep in mind, I'm just riffing here - the use case you're trying to solve isn't directly supported in the player.

Reply

Hi,

David: Did you also end up making any changes in the JW Player to improve the behavior you described above?

Pablo: I am facing a similar problem, and it didn't get addressed by changing wmode to "direct". We are testing on android, and switching streams is jumpy (video is not smooth), video lags behind audio, occasionally even the picture goes black for a few seconds. I am using 2 streams, 210Kbps and 460K, streaming from CloudFront using signed URLs.

When only 1 video is streamed (either one of the two, using only 1 level), the playback is smooth, there are no problems and no jumps. When both videos are streamed (2 levels), the problems happen.

The videos are encoded as mp4, with a keyframe every 3 seconds. (I tried 2 seconds as well.) Seems I'm doing everything by the book, but still have problems.

Any idea what could be wrong?

Regards,
Janusz

P.S. I have downloaded the JW player source, and will be trying to make 2 changes David suggested: increasing blacklist time or not allowing the player to return to a higher level scream.

Reply

P.S.
1. I'm using player version 5.9
2. Yes, I realize that your player doesn't use screams. I made a typo. :-)

Reply

@Janusz -

Do you have an example to look at? What platform(s) are you using to test?

Reply

Hi Pablo,

I have an example, but I don't want to post it in a world-readable forum. Can I send a link directly to you somehow?

Thanks,
Janusz

Reply

@Janusz -

You can email it to support [at] longtailvideo [dot] com. Please reference this thread.

Post new comment

  • Allowed HTML tags: <code> <blockquote> <em> <strong> <strike> <ul> <li> <ol>
  • You may post code using <code>...</code> .
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options