
This guide gives an overview of HTTP Video Pseudostreaming with the JW Player for Flash v5.
Both MP4 and FLV videos can be played back with a mechanism called HTTP Pseudostreaming. This mechanism allows your viewers to seek to not-yet downloaded parts of a video. Youtube is an example site that offers this functionality. HTTP pseudostreaming is enabled by setting the option provider=http in your player.
HTTP pseudostreaming combines the advantages of straight HTTP downloads (it passes any firewall, viewers on bad connections can simply wait for the download) with the ability to seek to non-downloaded parts. The only drawbacks of HTTP Pseudostreaming compared to Flash’s official RTMP Streaming are its reduced security (HTTP is easier to sniff than RTMP) and long loading times when seeking in large videos (> 15 minutes).
HTTP Pseudostreaming should not be confused with HTTP Dynamic Streaming. The latter is a brand-new mechanism currently being developed by Adobe that works by chopping up the original video in so-called chunks of a few seconds each. The videoplayer seamlessly glues these chunks together again. The JW Player does not yet support HTTP Dynamic Streaming.
HTTP Pseudostreaming does not work by default on any webserver. A serverside module is needed to enable it. Here are the two most widely used (and open source) modules for this:
Several CDN’s (Content Delivery Networks) support HTTP Pseudostreaming as well. We have done succesfull tests with Bitgravity, CDNetworks, Edgecast and Limelight.
Instead of using a serverside module, pseudostreaming can also be enabled by using a serverside script (in e.g. PHP or .NET). We do not advise this, since such a script consumes a lot of resources, has security implications and can only be used with FLV files. A much-used serverside script for pseudostreaming is Xmoov-PHP.
Under the hood, HTTP pseudostreaming works as follows:
When the video is initially loaded, the player reads and stores a list of seekpoints as part of the video’s metadata. These seekpoints are offsets in the video (both in seconds and in bytes) at which a new keyframe starts. At these offsets, a request to the server can be made.
When a user seeks to a not-yet-downloaded part of the video, the player translates this seek to the nearest seekpoint. Next, the player does a request to the server, with the seekpoint offset as a parameter. For FLV videos, the offset is always provided in bytes:
http://www.mywebsite.com/videos/bbb.flv?start=219476905
For MP4 videos, the offset is always provided in seconds:
http://www.mywebsite.com/videos/bbb.mp4?starttime=30.4
The server will return the video, starting from the offset. Because the first frame in this video is a keyframe, the player is able to correctly load and play it. Should the server have returned the video from an arbitrary offset, the player would not be able to pick up the stream and the display would only show garbage.
Note: Some FLV encoders do not include seekpoints metadata when encoding videos. Without this data, HTTP Pseudostreaming will not work. If you suspect your videos to not have metadata, use our Metaviewer plugin to inspect the video. There should be a seekpoints or keyframes list. If it is not there, use the FLVMDI tool to parse your FLV videos and inject this metadata.
When the player requests a video with an offset, it uses start as the default offset parameter:
http://www.mywebsite.com/videos/bbb.flv?start=219476905
http://www.mywebsite.com/videos/bbb.mp4?start=30.4
This name is most widely used by serverside modules and CDNs. However, sometimes a CDN uses a different name for this parameter. In that case, use the option http.startparam to set a custom offset parameter name. Here are some examples of CDNs that use a different name:
Here’s what an example SWFObject embed code looks like when both HTTP Pseudostreaming and a custom start parameter is enabled:
<div id='container'>The player will be placed here</div>
<script type="text/javascript">
var flashvars = {
file:'http://bitcast-a.bitgravity.com/botr/bbb.mp4',
provider:'http',
'http.startparam':'starttime'
};
swfobject.embedSWF('player.swf','container','480','270','9.0.115','false', flashvars,
{allowfullscreen:'true',allowscriptaccess:'always'},
{id:'jwplayer',name:'jwplayer'}
);
</script>
HTTP Pseudostreaming can also be enabled in playlists, by leveraging the JWPlayer namespace. Both the provider and http.startparam options can be set for every entry in a playlist. In this case, you don’t have to set them in the embed code (just point the file to your playlist).
Here’s an example, an RSS feed with a single video:
<rss version="2.0" xmlns:jwplayer="http://developer.longtailvideo.com/">
<channel>
<title>Playlist with HTTP Pseudostreaming</title>
<item>
<title>Big Buck Bunny</title>
<description>Big Buck Bunny is a short animated film by the Blender Institute,
part of the Blender Foundation.</description>
<enclosure url="http://myserver.com/botr/bbb.mp4" type="video/mp4" length="3192846" />
<jwplayer:provider>http</jwplayer:provider>
<jwplayer:http.startparam>apstart</jwplayer:http.startparam>
</item>
</channel>
</rss>
Instead of the enclosure element, you can also use the media:content or jwplayer:file element. More info in Create a Playlist with the JW Player.
Note: Do not forget the xmlns at the top of the feed. It is needed by the player (and any other feed reader you might use) to understand the jwplayer: elements.
Like RTMP Streaming, HTTP Pseudostreaming includes the ability to dynamically adjust the video quality for each individual viewer. We call this mechanism bitrate switching.
To use bitrate swiching, you need multiple copies of your MP4 or FLV video, each with a different quality (dimensions and bitrate). These multiple videos are loaded into the player using an mRSS playlist (see example below). The player recognizes the various levels of your video and automatically selects the highest quality one that:
As a viewer continues to watch the video, the player re-examines its decision (and might switch) in response to certain events:
Note: the player will not do a bandwidth switch if extreme bandwidth changes cause the video to re-buffer. In practice, we found such a heuristic to cause continous switching and an awful viewing experience. RTMP Streaming on the other hand, is able to switch seamlessly in response to bandwidth fluctuations.
Here is an example bitrate switching playlist (only one item). Note that it is similar to a regular HTTP Pseudostreaming playlist, with the exception of the multiple video elements per item. The mRSS extension is the only way to provide these multiple elements including bitrate and width attributes:
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"
xmlns:jwplayer="http://developer.longtailvideo.com/">
<channel>
<title>Playlist with HTTP Bitrate Switching</title>
<item>
<title>Big Buck Bunny</title>
<description>Big Buck Bunny is a short animated film by the Blender Institute,
part of the Blender Foundation.</description>
<media:group>
<media:content bitrate="1800" url="http://myserver.com/bbb-486.mp4" width="1280" />
<media:content bitrate="1100" url="http://myserver.com/bbb-485.mp4" width="720"/>
<media:content bitrate="700" url="http://myserver.com/bbb-484.mp4" width="480" />
<media:content bitrate="400" url="http://myserver.com/bbb-483.mp4" width="320" />
</media:group>
<jwplayer:provider>http</jwplayer:provider>
<jwplayer:http.startparam>apstart</jwplayer:http.startparam>
</item>
</channel>
</rss>
Some hints: