Question About Cross-Browser Audio and Video

This week’s question comes from Ben Henick.

What’s the best way to set up cross-browser audio and video content?

Sherpa Aaron Gustafson answers:

Adding audio and video content to a web page is nowhere near as easy as we might like it to be. It’s not that the syntax is hard, but rather that the codec wars have made it rather difficult. Since I’d like to end on a high note, let’s talk codecs first.

Codecs

As you’re no doubt well aware, there are numerous audio formats out there. Some, like WAV, have been around forever, while others, like Ogg Vorbis, are relatively new. Each audio file format offers its own attempt to strike a balance between file size and audio quality, but (much like software) each format is intellectual property and requires a license to decode it. Video is much the same, but is further complicated by the fact that a “video format” is actually a combination of a video codec and an audio codec, so in some cases playback requires two licenses. Some of these formats are freely licensed, but others cost big money.

Browser makers have considered the qualities of the different formats and their licensing terms, and have come up with wildly different ideas of what they want to support. Consequently, instead of being able to encode our audio or video in one format and calling it a day, we need to deliver our content in multiple formats. Thankfully, the HTML required to do so is relatively easy. Transcoding your source files into several formats, however, will take some time. Firefogg is a super-useful (and free) tool for that.

The Markup

As I mentioned, the HTML for adding audio and video content to a web page is pretty straightforward. Here’s a quick example of embedded audio:

<audio controls>
  <source src="my.mp3">
  <source src="my.og">
</audio>

This simple audio element offers the content in two formats: MP3 and Ogg Vorbis. Any browser that understands the HTML5 audio element will evaluate the source elements in order to determine which one to play. The first match wins. The browser is also instructed to provide native controls for playing, pausing, scrubbing, etc. by the use of the controls attribute.

Unfortunately, however, browsers that don’t recognize the HTML5 audio element will not show anything. This is because browser are instructed to ignore what they don’t understand.

To accommodate those browsers, we need to provide some fallback content. You could use Flash to do this, but my personal preference is simply to fall back to a list of download links:

<audio controls>
    <source src="my.mp3">
    <source src="my.oga">
    <p>Your browser can’t play this audio content directly, but you can download it:</p>
    <ul>
      <li><a href="my.mp3">Download as audio/mp3</a></li>
      <li><a href="my.oga">Download as audio/ogg</a></li>
    </ul>
</audio>

Video works in very much the same way. Here’s a simple example with three video formats:

<video controls="controls" width="640" height="480" poster="poster.png">
  <source src="my.m4v" type="video/mp4"/>
  <source src="my.webm" type="video/webm"/>
  <source src="my.ogv" type="video/ogg"/>
</video>

As with the audio example, this will work in any browser that recognizes HTML5 video element. The addition of a width and height aids with layout, and the poster attribute lets you set an image as the initial view of the video element. The type attribute also lets the browser know which MIME type is being used for each file (which aids it in determining which file it should play).

It’s worth noting that the source order has particular significance:

  1. Older iPhones will fail to play the MP4 video if it is not first, and
  2. Some browsers support both WebM and Ogg Theora, so you want to present the smallest file first.

Again, we need to provide a fallback for older browsers. I recommend the same setup for video as audio:

<video width="600" height="400" poster="poster.png" controls preload="none">
  <source src="my.m4v" type="video/mp4"/>
  <source src="my.webm" type="video/webm"/>
  <source src="my.ogv" type="video/ogg"/>
  <img src="poster.png" width="600" height="400" alt=""/>
  <ul>
    <li><a href="my.m4v">Download as video/mp4</a></li>
    <li><a href="my.webm">Download as video/webm</a></li>
    <li><a href="my.ogv">Download as video/ogg</a></li>
  </ul>
</video>

You could, of course, include a Flash player as a fallback as well, but I prefer to keep things simple.

I hope that helps!

Further Reading