Seeking videos beyond the buffer line

In this article we are going to address one simple and common problem, that is the ability to seek videos beyond the buffer line without having to buffer the whole video until the seek point.

Contents:

  1. Introduction
  2. Video delivery methods
  3. FLV pseudo-streaming
  4. MP4 pseudo-streaming
  5. HTML5 video pseudo-streaming

 

Introduction

Looking back in the years, when the average internet surfer was connecting to the internet with a modem, delivering video in web pages was not a simple task. The only problem was not the file size, but also the video format. Something that worked for Windows users may not have worked for Mac users, so webmasters had to offer their visitors different video formats. Even when the video format was compatible in various systems, embedding the video in a webpage was not consistent across different browsers and even same browsers in different operative systems.

With the time and the introduction of Flash video and FLV format in year 2002, it became easier to embed video in web pages in a consistent way across different browsers and operative systems, as long as the users had installed a Flash plugin. Flash evolved and in year 2007 added support for h.264 (MPEG-4 part 10) video codec in MP4 and F4V container formats, which provided better quality than the codecs used in traditional FLV containers such as the initial Sorenson Spark video codec in 2002, and the later addition of  On2 VP6 video codec in 2005.


Video Delivery Methods

When talking about video delivery, we can separate it into 3 categories.

Streaming, where a dedicated streaming server is used to deliver the video to the clients using specific protocols for that purpose, such as RTMP, HLS and RTSP/RTP. This approach provides great flexibility and control of the video delivery, but usually implies extra costs and complex setups.

Progressive Download, where the video file is sent to the client using the web server over the same HTTP protocol that is used to serve images and web pages. This approach is the most simple, but it has a major down side: to seek to any part of the video, the browser first needs to download the video file from the beginning to the seek point. This is far from ideal if you think for example a user wishing to view the last five minutes of an hour long video. In that case there is a waste of bandwidth from your server, and a waste of time for your client who is waiting until the video buffer reaches his desired seek point in time. Most of the video files won’t start playing until the whole file has been downloaded to the client machine. Some formats, such as FLV and MP4 can be optimized for progressive download, making them playable while the download is in progress.

Pseudo-streaming, where the server is configured to allow seeking the video to any position without the need to buffer the whole video until that point. For that purpose, FLV and MP4 video files need to be prepared (optimized) to allow seeking, and the encoding process should take into account the keyframe interval, to make video seeking faster.

Here we are going to focus on pseudo-streaming, and specially on pseudo-streaming of HTML5 video, which in fact is the simplest of all the options, and requires less or no server-side configuration at all, but will provide quick info about pseudo-streaming FLV and MP4 files too.


FLV Pseudo-streaming

In order to provide pseudo-streaming to your clients for video files encoded in FLV, you need to add support to your server for it, use a Flash player that supports pseudo-streaming, and prepare your FLV files with an special tool. The basic concept here is that the server receives a parameter along with the video file, indicating the starting point when the client clicks in the time line and returns video data from there.

Server side support:

Video files preparation:

The FLV video files need to be optimized for pseudo-streaming using a metadata manipulation application called flvtool2. Note that Tremendum Transcoder does this automatically for you (profile with faststart=true).

Flash player setup:

The Flash player that you use in your website also needs to support FLV pseudo-streaming. An excellent Flash player for that purpose is FlowPlayer, and they have a page explaining how to configure the player and more.


MP4 Pseudo-streaming

Using MP4 files with h.264 video has the advantage that the video files are not only playable via Flash player, but are also compatible with a big number of devices, and is currently one of the most commonly used formats to distribute high definition video. Another advantage of using MP4 instead of F4V is that the MP4 file is playable by mobile devices and some HTML5 web browsers. We will talk more about MP4 in the HTML5 pseudo-streaming section. Now let’s see how can we implement MP4 pseudo-streaming.

Server side setup:

  • Codeshop offers a h264 streaming module that is compatible with Lighttpd, Apache, Nginx, IIS and AOL web server.

Video files preparation:

The MP4 video files need to be optimized in order to allow progressive download by moving the metadata and offset information to the beginning of the file. That is done by reorganizing the moov atom using qt-faststart application. Note that Tremendum Transcoder does this automatically for MP4 and MOV files (profile with faststart=true).

Flash Player Setup:

Same as with FLV, the Flash player needs to be aware of the server side pseudo-streaming support to send the request in the appropriate format to seek in MP4 files. FlowPlayer supports both FLV and MP4 pseudostreaming.


HTML5 video pseudo-streaming

Video is one of the most important things of the internet nowadays, and with the introduction of HTML5, browsers have added support for native video playback. That means that it is no longer necessary to have your users install 3rd party plugins such as Adobe Flash or Microsoft Silverlight in order to watch video online. Still there’s not a single video and audio codec which is supported by all the HTML5 capable web browsers, as the specification does not require a video codec to be supported by all user agents (web browsers). This in turn means that to cover most of our audience, we need to provide alternate formats.

Currently we can cover almost all our audience by offering the video files in the following formats: MP4 (h.264 video, AAC audio), WebM (VP8 video, Vorbis audio) and Ogg ( Theora video, Vorbis audio). Both WebM and Ogg are open and royalty-free media file formats designed for web usage, while MP4 is patent encumbered and requires royalty payments for certain usages. Note that most of the browsers that support Ogg also support WebM, which is becoming the format of choice, and provides an excellent video quality.

Server side setup:

The best part of HTML5 pseudo-streaming is that most times the web server is ready out of the box. The only things that your server needs to do is support HTTP byte-range request, which the most popular web servers have enabled by default as part of the HTTP/1.1 specification, and provide the correct mime types for the video file extensions.

Serving with the correct mime types:

It is important that your web server provides the correct mime type to the clients placing the requests. If your server is not already configured, below you will find instructions for the major web server.

For Lighttpd, edit “conf.d/mime.conf” usually located in “/usr/local/etc/lighttpd/”, and add the following entries:

".ogg"  => "video/ogg",
".ogv"  => "video/ogg",
".ogm"  => "video/ogg",
".webm" => "video/webm",
".mp4"  => "video/mp4",

For Apache, you can edit “httpd.conf” usually located in “/etc/apache” or add the following custom mime types to a .htaccess in your server using the AddType directive:

AddType video/ogg  .ogg .ogv .ogm
AddType video/webm .webm
AddType video/mp4  .mp4

For Nginx, edit “mime.types” file located in your conf directory, usually under “/etc/nginx” and add the following lines:

video/ogg     ogg;
video/ogg     ogv;
video/ogg     ogm;
video/webm    webm;
video/mp4     mp4;

For information on adding custom mime types to IIS servers, see the official instructions for IIS6 and IIS7 respectively.

Checking for Accept-Ranges support:

You can check if your server supports “Accept-Ranges: Bytes” by testing the response headers using this online tool. Another way to check your server response headers is by using Chrome‘s developer tools (Ctrl + Shift + i), and switching to the Network tab, or using FireFox with FireBug extension (Open FireBug, click Net, and select enable).

By default most web servers that support HTTP/1.1 will provide an Accept-Ranges header. For example Lighttpd has a directive to enable or disable range requests, which by default is enabled.

Video files preparation:

From the 3 main video formats used to deliver HTML5 video (MP4, WebM and Ogg), only MP4 needs to be optimized for progressive download, the same way we do for MP4 Flash pseudo-streaming. It is worth noting that even if the MP4 file is not optimized, the client browser is capable of obtaining the metadata required to start playback by fetching the metadata from the end of the file using HTTP range requests.

Chrome playback of an optimized MP4 file.
Chrome playback of MP4 optimized media

Chrome playback of a non optimized MP4 file (notice the extra requests).
Chrome playback of MP4 media (non optimized)

In order to provide a good user experience we also need to consider the keyframe interval of the video files at the encoding time. A shorter keyframe interval will provide faster seek times at the cost of slightly increased file size. For example an interval of 60 frames will introduce a keyframe every 2 seconds in a 30fps video source. We can control this interval with the “-g #” parameter in the Tremendum Transcoder encoding profiles (where # is an integer number representing the interval).

Video player setup:

In contrast with Flash players where we need to do an explicit setup to support pseudo-streaming, native HTML5 video playback does not need anything extra. In the below example, we are using the 3 main video formats, so if the browser does not support the first, it will try the second, and so on.

<video controls preload="none" poster="perigny-poster.jpg"
 width="640" height="360">
  <source src="perigny.mp4"  type="video/mp4">
  <source src="perigny.webm" type="video/webm">
  <source src="perigny.ogg"  type="video/ogg">
</video>

View this example in a standalone page.

In order to test seeking beyond the buffer, I have setup lighttpd bandwidth limit to 256kb per second on video files, so if you are on a fast connection the buffer won’t get filled before you can try seeking to a non buffered area. To be able to test specific support of these media files, I have setup 3 different pages, each containing one source format only.

HTML5 video test using MP4 media only (h.264 video, AAC audio).
HTML5 video test using WebM media only (VP8 video, Vorbis audio).
HTML5 video test using Ogg media only (Theora video, Vorbis audio).

 

Reaching all audiences:

Not every browser supports HTML5 video, and not every HTML5 capable browser supports the same set of video formats. For this reason a common technique to reach the largest possible audience is to use HTML5 video with Flash fallback. In this setup, when the client browser does not support HTML5 video, the browser can still use Flash to play the video, or in the last instance, just download the video file.

There are many HTML5 video players out there, Kaltura maintains an excellent table with a comparison of many of them. For our fallback example, we are going to use VideoJS player.

View the VideoJS example page with MP4, WebM, Ogg and Flash player fallback.

Flash pseudo-streaming gotcha!:

As we have seen so far, HTML5 pseudo-streaming can be achieved out of the box without much trouble. All we need is an HTTP/1.1 compliant browser and serving the correct mime types. However, if we implement a Flash fallback, the server will need to be setup to support MP4 Flash pseudo-streaming and the fallback Flash player as well. Otherwise, visitors using a browser that does not support MP4 won’t be able to seek past the buffer line without waiting.

To illustrate this you can check the following VideoJS example which has an MP4 source only, in a browser that does not support MP4 format (for example Mozilla FireFox at the time of writing this article). You can refer to the HTML5 video browser support table from wikipedia to find out more.

View the VideoJS example page, with MP4 and Flash player fallback.

Test in your server:

In order to easily test if your server already supports all what is needed for a nice and smooth HTML5 video pseudo-streaming, you can download our example videos and pages in a zip file. Upload them to your browser and test seeking beyond the buffer line.

Download the test files (60 mb).

I hope this article helps you to deliver video to your visitors the way you want.