blue       earthtones
Streaming Video with Flowplayer and HTML5

 

November 2011: I'm actively researching and updating the information below as a result of a current project which has revealed some quirks using the <video> element. Stay tuned for some useful revisions!

Discussion: In 2009 I had the requirement to publish several "Web 2.0 RIA" High Definition videos on a client's website, and consequently investigated the wide range of choices available to accomplish this. There are easily a half-dozen potential solutions including .mov, .wmv, .avi, .mp4, .flv, and others. But in the end I concluded that Adobe Flash video provided the most effective solution for this requirement. A data point in the IEEE Computer Society's June 2009 issue reported that "98% of all Internet-connected PCs have a Flash player installed and the technology delivers 99% of all online video content viewed in the US" -- at least according to data gathered by Adobe. Statistics from StatOwl.com seem to bear this out, reporting that 97% of browsers have Flash support installed. I did observe that most videos I viewed during the process were in fact flv videos, and web stats from my own sites confirmed that the preponderance of visitors already had the Flash plugin installed -- importantly simplifying the user experience.

Naturally, this in turn led to days of next investigating Avid, Final Cut, Handbrake, Sorenson Squeeze, Windows Movie Maker, and other Mac and Windows products to facilitate cutting, editing, converting, compressing, and publishing Flash video.

Solution: Regardless of how you might import, convert, and compress an HD video to Flash video, it's the "every man's" and woman's solution, and furthermore it's a very straightforward matter to <embed> one or more Flash player(s) in a web page. That being said, I find that Flowplayer's API is handy for a variety of reasons. So, my conclusions for this requirement were Flash Video (.flv) with flowplayer, though I show some other options in the examples below.

Regardless of the player chosen, one thing to bear firmly in mind is the importance of video compression. The first video I published for this client was provided to me as an 80MB (3 minute) high definition DVD. Using Sorenson Squeeze, I compressed this to a 12MB Flash video, which was an important step since we've had as many as 800 viewers of this video over the course of a few hours.

Note that flowplayer will play a number of Flash-compatible formats including .flv, .mp4, and H.264, and I've verified support in IE 6+, Firefox, Safari, and Opera (with Javascript 1.5+ enabled). Beyond this, see an example of using the HTML5 <video> tag below with flowplayer as the fallback strategy for IE, which will not implement the <video> tag until the release of IE 9.

EXAMPLES OF EMBEDDED VIDEO

Flowplayer: Here's an example of multiple players on one page using flowplayer. These examples are short cuts of compressed high-definition, widescreen (i.e. 1.78:1 aspect ratio) videos that I imported from a pair of 32GB P-2 cards taken from a Panasonic AG-HPX camera shooting DVCPRO HD in January 2010. After roughly editing the raw video on a Mac, I compressed it with Sorenson Squeeze. Playing these is pretty standard Flowplayer fare in any browser, and this exact technique can be used to put an essentially unlimited number of players on one page. (You can view a production example of playing many HD videos on one page here. and an example of one larger video pane with "remote control" here). See playing the same video at left using the HTML5 <video> tag below.

 

HTML5  <video> TAG

This example uses the HTML5 <video> tag to play a video encoded as mime-type video/ogg with the preferred file extension .ogv. This video source is complemented with an alternate H.264 source (video/mp4) for Safari (and eventually IE9). The fallback strategy for IE 6-8 is implemented with flowplayer using the alternate .mp4

Support for the ogg/ogv format is inconsistent as seen here:

  IE 8 FF 3.5 Opera 10.5 Chrome3.0 Safari 3.0
Trident Gecko Presto WebKit WebKit
ogg No Yes Yes Yes No
mp4 No No No Yes Yes

 

Generating the Requisite HTML5 Video Files

For a variety of reasons, I find myself most often starting with a QuickTime movie (.mov) in hand whether I'm converting to Flash video (.flv) or any other format. To emit the videos for this example, it was only necessary to create two compressed versions from the source .mov  video:

  1. .ogv  for the canonical <source>
  2. .mp4  for the alternate <source>

The simplest way to convert a source .mov to the required HTML5 video formats is a straightforward three-step process:

  1. open the .mov with QuickTime Pro and export it as .m4v  (which is what QT chooses to name it)
  2. rename the .m4v file extension to .mp4  ( they're precisely the same format)
  3. use Firefogg to convert the .mp4  to .ogv (necessarily using Firefox)

Or, alternatively, just use Sorenson Squeeze on Mac or Windows to emit both.

The HTML5 Code

This is the code used in this example. It's a straightforward HTML5 <video> tag with fallback handling provided by flowplayer. It handles IE, Firefox, Safari, Chrome, and Opera, as well as media errors including mal-encoded video files and server mime-type errors. The conditional comment launches the video in IE which ignores the <video> tag.

This page uses an HTML5 <!DOCTYPE HTML> and is W3C validated. Note that playing the .mp4 in flowplayer requires Flash player 9.0.115 or above. Alternatively, you could just use example1.flv in the fallback code.


<video width="320" height="180" controls="controls" onerror="fallbackFlowplayer();">
    <source src="video/example1.ogv" type="video/ogg" />
    <source src="video/example1.mp4" type="video/mp4" /> 
    <script type="text/javascript">fallbackFlowplayer();</script>
</video>
<!--[if IE]>
    <script type="text/javascript">fallbackFlowplayer();</script>
<![endif]-->
	 

The supporting JavaScript code found in the page <head> is simply:


<script type="text/javascript" src="../js/flowplayer.min.js"></script>
<script type="text/javascript">
  function fallbackFlowplayer() {
    flowplayer("videoWindow", "../flash/flowplayer.swf", { 
        clip:  { 
           autoPlay: false, 
           autoBuffering: true
           }, 
        playlist: [
           "video/example1.mp4"
           ]
        });
    }
</script>