Configuring servers for Ogg media

  • Revision slug: Configuring_servers_for_Ogg_media
  • Revision title: Configuring servers for Ogg media
  • Revision id: 60420
  • Created:
  • Creator: Dikrib
  • Is current revision? No
  • Comment 1 words added, 1 words removed

Revision Content

Gecko 1.9.1 (Firefox 3.5) introduced support for HTML 5 audio and video media presentation without the need for the user to install any plug-ins or other software to do so. Prior to Firefox 4, Firefox supported only Ogg-encapsulated audio and video, which you may need to configure your server to support. In addition, there are several things you can do on the server side to optimize the performance of Ogg media when being presented by Firefox.

This article, based on a blog post by Chris Pearce, presents useful tips to help improve your server's presentation of Ogg media.

Serve Ogg media with the correct MIME type

*.ogg and *.ogv files containing video (possibly with an audio track as well, of course), should be served with the video/ogg MIME type. *.oga and *.ogg files containing only audio should be served with the audio/ogg MIME type.

If you don't know whether the Ogg file contains audio or video, you can serve it with the MIME type application/ogg, and Gecko will treat it as a video file.

Most servers don't by default serve Ogg media with the correct MIME types, so you'll likely need to add the appropriate configuration for this.

For Apache, you can add the following to your configuration:

AddType audio/ogg .oga
AddType video/ogg .ogv
AddType application/ogg .ogg

Serve X-Content-Duration headers

The Ogg format doesn't encapsulate the duration of media, so for the progress bar on the video controls to display the duration of the video, Gecko needs to determine the length of the media using other means.

There are two ways Gecko can do this. The best way is to offer an X-Content-Duration header when serving Ogg media files. This header provides the duration of the video in seconds (not in HH:MM:SS format) as a floating-point value.

For example, if the video is 1 minute and 32.6 seconds long, this header would be:

X-Content-Duration: 92.6

If your server provides the X-Content-Duration header when serving Ogg media, Gecko doesn't have to do any extra HTTP requests to seek to the end of the file to calculate its duration. This makes the entire process much more efficient as well as more accurate.

As an inferior alternative, Gecko can estimate the video length based on the Content-Length. See next point.

Don't use gzip/deflate compression

One common way to reduce the load on a web server is to use gzip or deflate compression when serving to a supporting web browser. When Firefox requests an Ogg media, it advertises that it can handle a gzipped or deflated response; the HTTP request includes the Accept-Encoding: gzip,deflate header. But despite Firefox advertising that it supports gzip/deflate, you probably don't want to gzip or deflate Ogg media. If you serve an Ogg media compressed, Firefox won't be able to seek in the media, or determine its duration. Since the video/audio data in Ogg files is already compressed, gzip/deflate won't actually save you much bandwidth anyway, so you probably want to disable compression when serving Ogg files.

Also, Apache servers don't send the Content-Length response header if gzip encoding is used.

{{ gecko_callout_heading("2.0") }}

Starting in Gecko 2.0 {{ geckoRelease("2.0") }}, Gecko will no longer request gzip or deflate compression when downloading media. The above is only relevant for Firefox 3.5/3.6.

Getting the duration of Ogg media

You can use the oggz-info tool to get the media duration; this tool is included with the oggz-tools package. The output from oggz-info looks like this:

 $ oggz-info /g/media/bruce_vs_ironman.ogv
 Content-Duration: 00:01:00.046

 Skeleton: serialno 1976223438
         4 packets in 3 pages, 1.3 packets/page, 27.508% Ogg overhead
         Presentation-Time: 0.000
         Basetime: 0.000

 Theora: serialno 0170995062
         1790 packets in 1068 pages, 1.7 packets/page, 1.049% Ogg overhead
         Video-Framerate: 29.983 fps
         Video-Width: 640
         Video-Height: 360

 Vorbis: serialno 0708996688
         4531 packets in 167 pages, 27.1 packets/page, 1.408% Ogg overhead
         Audio-Samplerate: 44100 Hz
         Audio-Channels: 2

Note that you can't simply serve up the reported Content-Duration line reported by oggz-info, because it's reported in HH:MM:SS format. You'll need to convert it to seconds only, then serve that as your X-Content-Duration value. Just parse out the HH, MM, and SS into numbers, then do (HH*3600)+(MM*60)+SS to get the value you should report.

It's important to note that it appears that oggz-info makes a read pass of the media in order to calculate its duration, so it's a good idea to store the duration value in order to avoid lengthy delays while the value is calculated for every HTTP request of your Ogg media.

Handle HTTP 1.1 byte range requests correctly

In order to support seeking and playing back regions of the media that aren't yet downloaded, Gecko uses HTTP 1.1 byte-range requests to retrieve the media from the seek target position. In addition, if you don't serve X-Content-Duration headers, Gecko uses byte-range requests to seek to the end of the media (assuming you serve the Content-Length header) in order to determine the duration of the media.

Your server should accept the "Accept-Ranges: bytes" HTTP header if it can accept byte-range requests. It must return "206: Partial content" to all byte range requests; otherwise, Gecko can't be sure you actually support byte range requests.

Your server must also return "206: Partial Content" for the request "Range: bytes=0-" as well.

If you're curious about why Gecko makes some of the HTTP requests it does, read comment 1 of bug 502894.

Include regular key frames

When Gecko seeks through Ogg media to a specified time, it has to seek to the nearest key frame before the seek target, then download and decode the video from there until the requested target time. The farther apart your key frames are, the longer this takes, so it's helpful to include key frames at regular intervals.

By default, ffmpeg2theora uses one key frame every 64 frames (or about every 2 seconds at 30 frames per second), which works pretty well.

Note: Of course, the more key frames you use, the larger your video file is, so you may need to experiment a bit to get the right balance between file size and seek performance.

Consider using the preload attribute

The HTML 5 audio and video elements provide the preload attribute, which tells Gecko to attempt to download the entire media when the page loads. Without preload, Gecko only downloads enough of the media to display the first video frame, and to determine the media's duration.

preload is off by default, so if getting to video is the point of your web page, your users may appreciate it if you include preload in your video elements.

See also

Revision Source

<p>Gecko 1.9.1 (Firefox 3.5) introduced support for HTML 5 <a class="internal" href="/En/HTML/Element/Audio" title="En/HTML/Element/Audio"><code>audio</code></a> and <a class="internal" href="/En/HTML/Element/Video" title="En/HTML/Element/Video"><code>video</code></a> media presentation without the need for the user to install any plug-ins or other software to do so. Prior to Firefox 4, Firefox supported only Ogg-encapsulated audio and video, which you may need to configure your server to support. In addition, there are several things you can do on the server side to optimize the performance of Ogg media when being presented by Firefox.</p>
<p>This article, based on a <a class="external" href="http://pearce.org.nz/2009/08/configuring-web-servers-for-html5-ogg.html" title="http://pearce.org.nz/2009/08/configuring-web-servers-for-html5-ogg.html">blog post by Chris Pearce</a>, presents useful tips to help improve your server's presentation of Ogg media.</p>
<h2 id="Serve_Ogg_media_with_the_correct_MIME_type">Serve Ogg media with the correct MIME type</h2>
<p>*.ogg and *.ogv files containing video (possibly with an audio track as well, of course), should be served with the <span style="font-family: Courier New;">video/ogg</span> MIME type. *.oga and *.ogg files containing only audio should be served with the <span style="font-family: Courier New;">audio/ogg</span> MIME type.</p>
<p>If you don't know whether the Ogg file contains audio or video, you can serve it with the MIME type <span style="font-family: Courier New;">application/ogg</span>, and Gecko will treat it as a video file.</p>
<p>Most servers don't by default serve Ogg media with the correct MIME types, so you'll likely need to add the appropriate configuration for this.</p>
<p>For Apache, you can add the following to your configuration:</p>
<pre>AddType audio/ogg .oga
AddType video/ogg .ogv
AddType application/ogg .ogg
</pre>
<h2 id="Serve_X-Content-Duration_headers">Serve X-Content-Duration headers</h2>
<p>The Ogg format doesn't encapsulate the duration of media, so for the progress bar on the video controls to display the duration of the video, Gecko needs to determine the length of the media using other means.</p>
<p>There are two ways Gecko can do this. The best way is to offer an <code>X-Content-Duration</code> header when serving Ogg media files. This header provides the duration of the video in seconds (<strong>not</strong> in HH:MM:SS format) as a floating-point value.</p>
<p>For example, if the video is 1 minute and 32.6 seconds long, this header would be:</p>
<pre>X-Content-Duration: 92.6
</pre>
<p>If your server provides the <code>X-Content-Duration</code> header when serving Ogg media, Gecko doesn't have to do any extra HTTP requests to seek to the end of the file to calculate its duration. This makes the entire process much more efficient as well as more accurate.</p>
<p>As an inferior alternative, Gecko can estimate the video length based on the Content-Length. See next point.</p>
<h2 id="Don't_use_gzip/deflate_compression">Don't use gzip/deflate compression</h2>
<p>One common way to reduce the load on a web server is to use <a class="external" href="http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/" title="http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/">gzip or deflate compression</a> when serving to a supporting web browser. When Firefox requests an Ogg media, it advertises that it can handle a gzipped or deflated response; the HTTP request includes the <code>Accept-Encoding: gzip,deflate</code> header. But despite Firefox advertising that it supports gzip/deflate, you probably don't want to gzip or deflate Ogg media. If you serve an Ogg media compressed, Firefox won't be able to seek in the media, or determine its duration. Since the video/audio data in Ogg files is already compressed, gzip/deflate won't actually save you much bandwidth anyway, so you probably want to disable compression when serving Ogg files.</p>
<p>Also, Apache servers don't send the Content-Length response header if gzip encoding is used.</p>
<div class="geckoVersionNote"> <p>{{ gecko_callout_heading("2.0") }}</p> <p>Starting in Gecko 2.0 {{ geckoRelease("2.0") }}, Gecko will no longer request gzip or deflate compression when downloading media. The above is only relevant for Firefox 3.5/3.6.</p>
</div>
<h2 id="Getting_the_duration_of_Ogg_media">Getting the duration of Ogg media</h2>
<p>You can use the <code>oggz-info</code> tool to get the media duration; this tool is included with the <a class="external" href="http://www.xiph.org/oggz/" title="http://www.xiph.org/oggz/"><code>oggz-tools</code></a> package. The output from <code>oggz-info</code> looks like this:</p>
<pre><code> $ oggz-info /g/media/bruce_vs_ironman.ogv
 Content-Duration: 00:01:00.046

 Skeleton: serialno 1976223438
         4 packets in 3 pages, 1.3 packets/page, 27.508% Ogg overhead
         Presentation-Time: 0.000
         Basetime: 0.000

 Theora: serialno 0170995062
         1790 packets in 1068 pages, 1.7 packets/page, 1.049% Ogg overhead
         Video-Framerate: 29.983 fps
         Video-Width: 640
         Video-Height: 360

 Vorbis: serialno 0708996688
         4531 packets in 167 pages, 27.1 packets/page, 1.408% Ogg overhead
         Audio-Samplerate: 44100 Hz
         Audio-Channels: <span style='font-family: "Courier New","Andale Mono",monospace;'>2</span></code>
</pre>
<p>Note that you can't simply serve up the reported Content-Duration line reported by <code>oggz-info</code>, because it's reported in HH:MM:SS format. You'll need to convert it to seconds only, then serve that as your <code>X-Content-Duration</code> value. Just parse out the HH, MM, and SS into numbers, then do (HH*3600)+(MM*60)+SS to get the value you should report.</p>
<p>It's important to note that it appears that <code>oggz-info</code> makes a read pass of the media in order to calculate its duration, so it's a good idea to store the duration value in order to avoid lengthy delays while the value is calculated for every HTTP request of your Ogg media.</p>
<h2 id="Handle_HTTP_1.1_byte_range_requests_correctly">Handle HTTP 1.1 byte range requests correctly</h2>
<p>In order to support seeking and playing back regions of the media that aren't yet downloaded, Gecko uses HTTP 1.1 byte-range requests to retrieve the media from the seek target position. In addition, if you don't serve <code>X-Content-Duration</code> headers, Gecko uses byte-range requests to seek to the end of the media (assuming you serve the <code>Content-Length</code> header) in order to determine the duration of the media.</p>
<p>Your server should accept the "<code>Accept-Ranges: bytes</code>" HTTP header if it can accept byte-range requests. It must return "<code>206: Partial content</code>" to all byte range requests; otherwise, Gecko can't be sure you actually support byte range requests.</p>
<p>Your server must also return "<code>206: Partial Content</code>" for the request "<code>Range: bytes=0-</code>" as well.</p>
<p>If you're curious about why Gecko makes some of the HTTP requests it does, read <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=502894#c1" title="https://bugzilla.mozilla.org/show_bug.cgi?id=502894#c1">comment 1 of bug 502894</a>.</p>
<h2 id="Include_regular_key_frames">Include regular key frames</h2>
<p>When Gecko seeks through Ogg media to a specified time, it has to seek to the nearest key frame before the seek target, then download and decode the video from there until the requested target time. The farther apart your key frames are, the longer this takes, so it's helpful to include key frames at regular intervals.</p>
<p>By default, <a class="external" href="http://v2v.cc/~j/ffmpeg2theora/" title="http://v2v.cc/~j/ffmpeg2theora/"><code>ffmpeg2theora</code></a> uses one key frame every 64 frames (or about every 2 seconds at 30 frames per second), which works pretty well.</p>
<div class="note"><strong>Note:</strong> Of course, the more key frames you use, the larger your video file is, so you may need to experiment a bit to get the right balance between file size and seek performance.</div>
<h2 id="Consider_using_the_preload_attribute">Consider using the preload attribute</h2>
<p>The HTML 5 <a class="internal" href="/En/HTML/Element/Audio" title="En/HTML/Element/Audio"><code>audio</code></a> and <a class="internal" href="/En/HTML/Element/Video" title="En/HTML/Element/Video"><code>video</code></a> elements provide the <code>preload</code> attribute, which tells Gecko to attempt to download the entire media when the page loads. Without <code>preload</code>, Gecko only downloads enough of the media to display the first video frame, and to determine the media's duration.</p>
<p><code>preload</code> is off by default, so if getting to video is the point of your web page, your users may appreciate it if you include <code>preload</code> in your video elements.</p>
<h2 id="See_also">See also</h2>
<ul> <li><a class="internal" href="/en/Using_HTML5_audio_and_video" title="En/Using audio and video in Firefox">Using audio and video in Firefox</a></li> <li><a class="internal" href="/En/Media_formats_supported_by_the_audio_and_video_elements" title="En/Media formats supported by the audio and
    video elements">Media formats supported by the audio and video elements</a></li> <li>{{ interface("nsIDOMHTMLMediaElement") }}</li>
</ul>
Revert to this revision