Go
Not registered? Sign up!

HTTP Video Streaming

Google Translate
HTTP Video Streaming

There are two ways to deliver video files over the web: (i) progressive download and (ii) streaming. Progressive downloads are typically cheaper and work with any server, but do not offer content protection nor seeking to undownloaded parts. Streaming servers (e.g. FMS, Wowza or Red5) offer these functionalities, but must be installed on your server(s). Since server side access and / or knowledge is not always readily available, some developers choose an “in between” solution of HTTP streaming through the use of a small server side script (e.g. PHP, ASP, etc.). This section will describe such methods.

An Example

HTTP streaming works through a very simple mechanism. Every time a seek operation is performed, the media player makes a request to the server side script with a couple of GET variables. One is the file to play and one is the start position. The server side script then starts the video from the offset given. Below is a short example. After you start the video, you can directly jump to any part in the video without having to wait until it is loaded.

This streaming setup uses three components:

  1. A Flash Player (the JW Player).
  2. A serverside script (the XMoov-PHP script). Please Google or search the forum for ASP, C# and other implementations.
  3. An FLV video that contains keyframes metadata. Your FLV files already likely have this. If not, use a patcher like FLVMDI to fix your videos.

This div will be replaced

Example Setup

The JW Player used in this example is version 4.1, since this one introduced many advanced HTTP streaming features (see below). After you’ve added the player to your web page using either a standard embed code or SWFObject, you can tell the player to use HTTP streaming by adding one additional flashvar, streamer, which is set to the location of the server side script:

<p id='example' class="media">Here the video will be shown.</p>

<script type='text/javascript'>
  var s1 = new SWFObject('/jw/upload/player.swf','ply','420','250','9','#ffffff');
  s1.addParam('allowfullscreen','true');
  s1.addParam('flashvars','file=bunny.flv&streamer=/jw/embed/xmoov.php');
  s1.write('example');
</script>

In this example, we’ll use the xmoov-php script, which can be downloaded here. There are a few settings in this script, which you can recognize by the define() functions. The ones you must set are:

  1. XMOOV_PATH_ROOT: the root path of your website on your server (e.g. /var/www/html/).
  2. XMOOV_PATH_FILES: the folder in which your videos are stored (e.g. videos/).
  3. XMOOV_GET_FILE: the variable used for the video to play. (this should be file with the JW Player).
  4. XMOOV_GET_POSITION: the variable used for the start position. (this should be start with the JW Player).

If the video you use has the correct metadata, you should be able to seek to non-downloaded parts. If it doesn't work, you can try loading the xmoov.php script directly within your browser window. Add the URL of your FLV by calling xmoov.php?file=yourvideo.flv&position=0 to see if there are any error messages.

If everything worked, you’ve successfully setup basic HTTP streaming. Let's continue with a couple of pointers on more advanced functionalities: bandwidth throttling, video security and adaptive streaming.

Bandwidth Throttling

Bandwidth throttling is a technique that squeezes the download speed of your videos; your videos are downloaded only a fraction faster than they can be watched, so you don't waste any bandwidth on unwatched content. The xmoov-php script has bandwidth throttling built-in, and you can enable it by setting the following variables:

  1. XMOOV_CONF_LIMIT_BANDWIDTH: enables throttling; set to TRUE.
  2. XMOOV_BW_PACKET_SIZE: the size of each chunk of video to send; set this a number (e.g. 100; see below).
  3. XMOOV_BW_PACKET_INTERVAL: the time to wait before the next package is sent; set this to a number (e.g. 1; see below).

The combination of the latter two variables defines the download speed. A 100k package every second (as set up here) throttles to 100 kilobytes / second and should be used for videos of about 80 kilobytes / second (or 600 kilobits per second). Tweak both variables until you arrive at a speed that works best with your content (this will depend on the bit rate of your videos).

Note that runtime bandwidth checking is not built into the JW Player yet. If you have any suggestions regarding this issue, please let us know. Some of our best features have come from our community.

File Security

The JW Player 4.1 introduced the ability to secure your streaming videos through a token; a secret string sent from the player to your web server. The web server can use this to verify if the player or browser that requests the video is authorized to do so. Such token-based security is quite effective against leeching, which is the direct streaming of your videos from someone else's website (they get the page views, you pay the bill). It is also helpful against illegal downloading of your videos, though this practice can never be fully circumvented. The token feature is also available to RTMP (integrating with the Wowza Securetoken), but we'll deal with HTTP streaming here.

You can set a token by adding a flashvar called token to the JW player embed code. Say we set the value to K49sS9q0, the JW Player will send the value of this token along with every request to a video that is being made.

In xmoov-php, you can check the value of this token by setting the XMOOV_GET_AUTHENTICATION to token and adding a small check right below that (or above the "PROCESS FILE REQUEST" section). See the example below:

define('XMOOV_GET_AUTHENTICATION', 'token');
if($_GET[XMOOV_GET_AUTHENTICATION] != 'K49sS9q0') {
   header("HTTP/1.0 401 Access Denied");
   exit;
}

With this code, if a site requests your video without the correct token, they will get a 'video not found' or 'access denied' message. If you change the token quite frequently (e.g. every ten minutes), other websites can never access your content any longer than a few minutes, even if they used a complete URL that included the ?token=K49sS9q0 parameter. Leechers be gone.

Unfortunately, this type of security doesn't help much against illegal downloading of your content. It blocks people who search your HTML code for video URLs, but it doesn't prevent HTTP sniffers from discovering the precise URL. In order to block those, you must find a mechanism that makes every URL unique for every play, so it never can be requested more than once. Building such a mechanism is a little beyond this tutorial, but it can be done by letting the JW Player perform a small operation on the token before it is returned to the server side script. Because the server also knows the value of the initial token and the operation performed in the player, it could keep a list of allowed unique tokens to match against.

Adaptive Streaming

Next to the file and start variables, the JW Player sends additional variables to the server side script. You can use these to determine which video file to return and thus build an adaptive streaming mechanism. Here's a full list of all parameters sent:

  1. file: the flv file to play.
  2. start: the start position in bytes inside the FLV file.
  3. token: a string through which you can setup video security (see above).
  4. id: the id of the media player in the HTML DOM. You can use this for multiple types of checks.
  5. version: the version of the JW Player. This can be used for version compatibility; should a new version have additional functionality, you can distinguish them using this parament.
  6. client:the type and version of the Plugin, for example FLASH WIN 9,0,124,0. You can use this for example to return higher quality videos to Flash Plugins that have fullscreen capabilities (everything above 9,0,28,0).

The client variable could in theory also be used to stream FLV or MP4 videos into the player, since the Flash Plugin 9,0,98,0 introduced the ability to stream MP4 videos. However, the MP4 container format is completely different from the FLV format. While the FLV format is perfectly suited for HTTP streaming through scripts like xmoov-php, MP4 streamer scripts must perform additional server side processing in order to return the right headers and container data with each seek.

One way to benefit from the new H.264 video and AAC audio and still use HTTP streaming is to encode your videos with H.264 / AAC, but mix them in an FLV container. Note: This can be done with tools like FFMPEG, though it’s not recommended by Adobe, as you'll loose the ability to spread the file across multiple devices such as smart phones or iPods.

Lighttpd

With Apache or IIS, you add HTTP streaming through a server side script, which negatively impacts performance. One web server without this performance issue is the Lighttpd web server. It includes a module for HTTP FLV streaming, so if you use this server you can HTTP stream out-of-the-box. The JW Player is completely Lighttpd-compatible; simply set the streamer flashvar to lighttpd and the player can seek to non-downloaded parts.

There's also a module for streaming MP4 files for the Lighttpd server. This module does all the server side processing needed to mix an MP4 container on the fly for every seek request. As before, you can activate the functionality if you add an MP4 file and set the streamer flashvar to lighttpd. Here's an example with a ten minute video:

This div will be replaced

JW Player - Flash Video Player

JW Player - Flash Video Player Download the world's most popular open source player. It supports FLV, MP3, MP4 & AAC; it's Plugin-extensible; and it's fully integrated with our AdSolution. No wonder it's #1.

Monetize Your Video

Monetize Your Video Earn money with ads from LongTail's AdSolution. Watch our demos and sign up now!