Streaming Tutorial II:
HTML 5 and iPad-friendly Video from your own Web Site

Making videos compatible with multiple browsers and devices
October 4, 2010 (last updated December 15, 2011)

  
  PREFACE
Let me start by pointing out that Mark Pilgrim, the author of Dive Into HTML5, has done a similar tutorial to this one, only much more comprehensive, accurate, and better written. So you should definitely read his if mine doesn't work for you. [Aside: Mark Pilgrim took down many of his accounts and sites in early October 2011, but I have updated my links to point to community mirrors of his removed works.] Another tutorial similar to this one is Video for Everybody, by Kroc Camen.

THE CHANGING FACE OF WEB VIDEO
I wrote my first video streaming tutorial in July 2009, but then in September 2010, Firefox 3.5 changed the game and came out with new HTML 5.0 features including embedded video which no longer requires an Adobe Flash Player plugin to display. Today virtually every major browser supports HTML 5.0 embedded video, as does YouTube (see YouTube's blog article about HTML5 vs. Flash). This makes it easier than ever to have your videos play on as many platforms as possible (PCs, iPhones and other smartphones, iPads and other tablets) without requiring Adobe Flash Player, which iPads and iPhones do not support.

THE VIDEO FORMAT WAR
The one fly in the ointment for web video today is that there are two major competing video formats supported by different companies for various reasons (see the table below). The latest versions of Mozilla Firefox, Google Chrome, Opera, and YouTube all support WebM (VP8/Vorbis). WebM is open source (it was released by Google as open source in May 2010) and supposedly unencumbered by patents. Microsoft and Apple, on the other hand, prefer the MP4 container format with H.264 encoded video, though the WebM Project has a web page devoted to getting .webm videos running in IE9. Even if IE9 directly supports WebM, though, it doesn't help, because Apple remains entrenched in the MP4/H.264 camp. The reason Google and Mozilla prefer WebM is that MP4/H.264 has legal issues involving patents and licenses. H.264, on the other hand, has very widespread hardware support in present-day computers and portable devices for video playback. Yet another alternative video format is the open-source Ogg (Theora/Vorbis) format supported by some browsers, but it seems to have been made largely obsolete by WebM at this point.

NECESSARY PIECES
You may want to encode your video in up to three different formats to support most browsers, but with Firefox 4.0 approaching 10 million downloads per day in its first few days of release (March 22, 2011), I suspect that just the MP4 and WebM formats will soon be sufficient, and Ogg will be less and less necessary:

Container
Format
File
Extension
Video
Encoding
Audio
Encoding
Supporting
Browsers
MP4 .mp4 H.264 AAC or MP3 Safari 3.0+ (Apple), IE 9.0+ (Microsoft), Chrome 5.0+ (Google)**, iPhone 3.0+, Android 2.0+
WebM .webm VP8 Vorbis Firefox 4.0+, Chrome 5.0+, Opera 10.6+, IE 9.0+*
Ogg .ogv Theora Vorbis Firefox 3.5+ (Mozilla); Chrome 5.0+, Opera 10.5+
* - IE9 to support WebM only with user-installed codec
** - As of Jan 11, 2011, Google plans to drop H.264 support from Chrome.


For compatibility with older browsers which don't support embedded video, you'll also need FLV hosting.com's Flash-based video player file, YTPlayer.swf (local copy--right click it and select "Save link as ..."). This small file must be in the same folder as your html file which launches it. It launches a player using Adobe's Flash Player plugin. Thank you to FLV hosting for this nice player. The YTPlayer.swf will play the .mp4 file, fortunately (no need to have a different format just for this player). You'll then need a way to convert your video files to .mp4 and .webm (and .ogv if you like). See below for more on how to do that.

Finally, you may need to contact your web hoster and have them modify their server mime types according to the instructions on this page (see the Server Support section). Be sure to also add video/webm to the mime types for WebM support. I had to do this, but my web hoster responded very quickly and was happy to oblige. Note that some hoster control/config pages allow you to change your mime types yourself. You might want to check yours.

HTML EXAMPLE
After getting YTPlayer.swf, and converting your video to the .mp4 and .webm file formats (see next section) you need to create an HTML file to show the video.

  Here is an HTML example. The example includes .ogv video, but these days I just post .webm and .mp4 versions of my videos. The HTML source is below:

  <!doctype html>
  <html>
  <style type="text/css"><!-- img { display:block } video {display:block} --></style>
  <body bgcolor=#c0ffc0><center>
  <font face="calibri,arial,sans-serif">
  <h1>Cat Food Burglar</h1>
  <font color=#008000 size=+2><b>VIDEO</b></font><br>
  <table width=0 cellpadding=0 cellspacing=0 border=4 bordercolor=#008000><tr><td>
  <!-- Actual video file is 480x360 -->
  <video width="480" height="360" controls autoplay>
      <!-- .mp4 file must come first for Safari.  IE9 will also play it. -->
      <source src="cat_food_burglar.mp4" />
      <!-- Firefox 4.x, Google Chrome, and Opera will play the .webm format -->
      <source src="cat_food_burglar.webm" />
      <!-- Firefox 3.5/3.6 will only play .ogv files -->
      <source src="cat_food_burglar.ogv" />
      <!-- If all else fails, the script below will try to launch the Flash player. -->
      <embed
          src="YTPlayer.swf"
          flashvars="movieName=cat_food_burglar.mp4&autoStart=true"
          width=480
          height=390
          allowFullScreen=true
          type="application/x-shockwave-flash"
          pluginspage="http://get.adobe.com/flashplayer" />
      </video>
  </td></tr></table>
  <br>
  <font size=+1>Hidden camera catches my dog swiping cat food.</font>
  <br><br>
  <table border=0><tr>
  <td valign=top align=left>Downloads:</td>
  <td valign=center align=center><a href="cat_food_burglar.mp4">.mp4</a><br>
  <font size=-1>7.4 MiB<br>805 kibps</font></td>
  <td valign=center align=center><a href="cat_food_burglar.webm">.webm</a><br>
  <font size=-1>6.7 MiB<br>732 kibps</font></td>
  <td valign=center align=center><a href="cat_food_burglar.ogv">.ogv</a><br>
  <font size=-1>6.7 MiB<br>729 kibps</font></td>
  </tr></table>
  <font size=-1 color=black>If the video doesn't play, upgrade to the latest
  <a href="http://firefox.com">Firefox browser</a><br>
  or download and install 
  <a href="http://get.adobe.com/flashplayer/">Adobe FlashPlayer</a>.</font>
  </font>
  </center></body></html>

Note that without the first line of the HTML source above (<!doctype html>), IE9 will not interpret the <video> tag correctly. The only files in the folder on the server are: index.html (listed above), YTPlayer.swf, and the video files, cat_food_burglar.mp4, cat_food_burglar.ogv, and cat_food_burglar.webm.

Here is another example which shows you which file your web browser is using.
And these examples will test if your browser can play .mp4, .webm, and/or .ogv videos.

CREATING THE .mp4 and .webm (and .ogv) FILES
There are a number of ways to convert (encode) your video files to the necessary video file formats:

1. Upload your video file to YouTube.com. YouTube will automatically convert just about any video format to a high-quality .mp4 file which you can then download and remove from their server. With their HTML 5 project, they may also be converting to .webm. I'm not sure.

2. Check out the encoding instructions in Mark Pilgrim's tutorial. The table of contents has links to step-by-step instructions on how to encode to Ogg with FireFogg, how to encode to H.264 with HandBrake, and how to encode to WebM with FFmpeg.

3. I use FFmpeg, a command-line utility which will convert/scale/crop between many different video and audio formats. See the FFmpeg section of my utility software page for more details. I recommend this page (32-bit static build) for a good Windows version of ffmpeg.exe that encodes to all the types listed below. See my ffmpeg/avconv benchmark page for more on why. If you google around, you should be able to find a user-friendly, GUI front-end for FFmpeg, but I just use it from the command line. This is the command I use to convert my hi-def Panasonic camera videos to .mp4 files:
  ffmpeg -threads 4 -i input_video.mts -i_qfactor 0.71 -qcomp 0.6
         -qmin 10 -qmax 63 -qdiff 4 -trellis 0 -vcodec libx264 
         -s 640x360 -b:v 1000k -b:a 56k -ar 22050 output_video.mp4
...and this command to convert to .webm files (libvpx vcodec):
  ffmpeg -threads 2 -i input_video.mts -s 640x360 -qmax 63 -b:v 1000k
         -b:a 56k -ar 22050 -acodec vorbis output_video.webm
...and finally this command to convert to .ogv files (libtheora vcodec):
  ffmpeg -i input_video.mts -s 640x360 -qmax 63 -b:v 1000k
         -b:a 56k -ar 22050 -acodec vorbis output_video.ogv
The above commands convert input_video.mts (can be .avi or other type) to output_video.mp4 using h.264 encoding (-vcodec libx264) and a target bit rate of 1000 kibps; or to output_video.webm or to output_video.ogv using the same parameters. The output video size is 640 x 360. You'll want to make sure the output video size matches the aspect ratio of your videos (mine are hi-def, so they are 16:9, but most standard def videos are 4:3, so you'd use -s 480x360). The -b:a 56k and -ar 22050 set the audio so it will be compatible with the video players.

Other FFmpeg (and avconv) notes:
  • The -b:v and -b:a options are new options for the bitrate used by the very latest versions of ffmpeg.exe (or avconv.exe) (October 2011 or after). Download a more recent version if your version doesn't understand these options.
  • All of the extra parameters in the mp4 conversion command are there to get the h.264 encoding to go smoothly. I've made them part of a Windows batch (script) file so I don't forget them.
  • The -qmax 63 option above allows the use of maximum compression (63 is the highest value allowed) on the video frames in order to achieve the desired video bit rate (-b:v 1000k). Setting this value lower will improve the video quality, but the requested bit rate (-b:v option) rate may not be achieved.
  • The -threads option enables multiple threads to do the encoding, which will make FFmpeg encode faster on a multi-core/multi-threaded CPU. Not all encoders take advantage of this option. See my ffmpeg/avconv benchmark page for how well different encoders perform using multiple threads.
  • As of October 2011, ffmpeg.exe or avconv.exe from libav.org require the additional command-line option -strict experimental to encode to AAC audio when creating the .mp4 file.
  • Also as of October 2011, only ffmpeg.exe or avconv.exe windows binaries from ffmpeg.org encode to .webm or .ogv. Again, see my ffmpeg/avconv benchmark page for what versions do what encoding.
  • FFmpeg has much more capability--it can crop your video, scale it, take a specific time slice, etc. For more about how to use FFmpeg, see the FFmpeg documentation page. For example, adding the arguments -ss 7 -t 35 to the conversion commands above would start 7 seconds into the source video and convert the next 35 seconds to the output video.

4. There are many other .mp4, .ogv, and .webm encoders to convert your video files. Just google "mp4 (or ogv or webm) encoding".

That's all for now. Good luck and have fun!