ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Adding Multiple Bitrate Support to Flash Video with the Open Video Player
http://www.actionscript.org/resources/articles/1008/1/Adding-Multiple-Bitrate-Support-to-Flash-Video-with-the-Open-Video-Player/Page1.html
Haik Sahakian
Web developer living in New York. Familiar with Galaga and ZX81 BASIC. Haik Sahakian
 
By Haik Sahakian
Published on May 13, 2010
 
Customizing the Open Video Player's Flash  library to switch between multiple bitrates on different network and CPU environments.

The Open Video Player's ActionScript library for Flash and Flex offers an easy way to add multiple bitrate support into a video player. It comes with 3 built-in rules to determine when to switch between different bitrates: the BandwidthRule, BufferRule, and FrameDropRule classes. When playing multiple bitrate video, these rules are checked every two seconds to see if a bitrate switch should take place.

The bitrate switching logic can be customized to prevent switching bitrate too often, or not often enough. This article outlines how to modify the OVP code to switch efficiently on different network and CPU environments.


Contents
  • Commonly modified parameters
  • Modifying the OVP code
  • Limiting client-server bandwidth
  • Ignoring consistently unsuccessful bitrates
  • Reacting to dropped frames
  • Downloading the Open Video Player's Flash library

Commonly modified parameters

OVP's classes allows a Flash video player to quickly tune the most commonly modified parameters to fit with different network conditions, processing power, and video length.

The BandwidthRule, BufferRule, and FrameDropRule classes contain parameters that are commented as tunable at the top of each class file. For example, the collowing code appears in FrameDropRule.as:

[as]/* TUNABLE PARAMETERS FOR THIS RULE */

private const DROP_ONE_FRAMEDROP_FPS:Number = 10;
private const DROP_TWO_FRAMEDROP_FPS:Number = 20;
private const PANIC_FRAMEDROP_FPS:Number = 24;

/* END TUNABLE PARAMETERS */[/as]

The parameters marked as tunable in the three rule classes allow you to set the frames per second, bandwidth headroom, and read-ahead buffer settings that you want the player to maintain.


Modifying the Open Video Player code


You may also need to modify the OVP code to switch between bitrates successfully. If your player does not switch to a higher bitrate when it should, this may be because it is limiting its own bandwidth, or remembering poor results with that bitrate in the past. Finally, the frames per second and buffering checks that occur before allowing a switch up may need to be relaxed.


Limiting client-server bandwidth


To make streaming more efficient, the setRateLimits() function in the OvpDynamicNetStream class asks Flash Media Server to set a bandwidth limit on its connection to the player. By default, this limit is set at 140% of the current video bitrate. This is typically much less than the actual bandwidth capabilities of the network.

The OVP documentation says this is to prevent the client buffer from growing too large and making bitrate switches take longer to occur as a previous bitrate's buffer is used up. Flash 10.1 will change this behavior to switch to new bitrates faster by not waiting for an old bitrate's buffer to complete. Setting the maximum buffer length on the client is an easier way of tuning the buffer, though setting a lower bandwidth limit can allow the server to more predictably manage the number of clients it is connected to.

If the range of bitrates for your video are spaced far apart, limiting the bandwidth in this way can prevent a player from ever thinking it has enough bandwidth for a switch up. For example, if the bandwidth has been limited to 140% of your current video, and the next video was encoded at twice the bitrate, the client will not think it has enough network capacity for this 200% jump.

To prevent this, you can customize the setRateLimits() code to maintain enough bandwidth to allow for the jumps between your video's bitrates, or just set the bandwidth limit at startup to always be about 140% of your highest bitrate. It needs to be high enough above the highest bitrate so that the BandwidthRule does not think that it is in danger of running short, and switch down.

Here is an example of the setRateLimits() function setting the bandwidth to be 4000kbps:

[as]private function setRateLimits(index:int):void
{
// set rate limit to always be 4000kbps
var newRate:Number = 4000 * 1024 / 8;
_nc.call("setBandwidthLimit",null, newRate, newRate);
}[/as]


Ignoring consistently unsuccessful bitrates

The Open Video Player library keeps track of how successful each bitrate is when playing multi-bitrate video. If a particular bitrate fails to play more than 3 times, it will not try to play it again. However, every switch down from a bitrate is counted as a failure to play, so this error threshold is often reached, especially for videos more than a few minutes long.

Simply switching to another window for a few seconds, or a short but CPU-intensive background task, can cause a video's frames per second to suffer, and a switch to a lower bitrate to occur. 3 such events for a particular bitrate will cause the "out of the box" OVP code to remove that bitrate from consideration for a switch up. If a video plays for long enough, the real-world fluctuations in displayed frames per second can cause a video to accumulate enough errors that only the lowest quality file will play.

To prevent this, you can either modify the feature, or remove it. You can adjust the number of permitted switches to lower bitrates to match the length of the video and network conditions, and you could allow a bitrate to wipe errors from its record (for driving too slowly) when it plays a video successfully for a set amount of time.

To modify the OVP code, you will need to update the OvpDynamicnetStream class. The existing class increments a bitrate's fail count in the switchToIndex() function, when a switch to a lower bitrate occurs:

[as]_dsi.incrementFailCountAt(_streamIndex);[/as]

Sometimes the feature isn't appropriate. As long as the URLs to your video bitrates are valid, removing the player's ability to block them will result in the player constantly checking for the best bitrate to play. When available bandwidth and CPU change frequently, this may be the best choice.

To remove the feature, edit the isAvailable() function in the DynamicStreamItem class to always return true.

[as]public function isAvailable(index:int):Boolean
{
return true;
}[/as]


Reacting to dropped frames


The OVP allows for performance fluctuations by waiting for at least 10 dropped frames per second before reducing the bitrate. However, just 2 dropped frames per second will prevent a switch up to a higher bitrate. On less powerful computers this can hold back a switch to a higher bitrate for longer than the user may expect.

This occassional sluggishness can be a case for allowing a user to control the bitrate through the player controls. Allowing users to switch to higher bitrates before their time often results in jumpy playback. However, they tend to blame the network for this rather than the player cheers cheers.

The OVP's default values of 10 dropped frames for a switch down and 2 dropped frames to prevent a switch up have worked well in my experience. If the limit of 2 dropped frames per second is too strict for a video player's users, you can modify the getNewIndex() function in BandwidthRule.as. The key line is:

[as]newIndex = (_metrics.droppedFPS < 2 && _metrics.bufferLength > _metrics.targetBufferTime) ? newIndex : -1;[/as]


Downloading the Open Video Player's Flash library

The OVP library for Flash and Flex is available on SourceForge, together with the project's documentation and support forum.