Delivering HTML5 video and fallback support with the help of Video JS

With HTML5 video and the current support in web browsers, we need to cater to different codecs, and fallbacks for web browsers with no native video support. This is where Video JS steps in.

What it is

Video JS is a little JavaScript library that helps with feature and codec detection, and also delivering Flash fallbacks where that is applicable. It offers general control and additionally skinning capabilities of the video presentation. I’ve used it recently where I needed a video to be playable across as many platforms as possible, and I was quite happy with the results.

Converting video

If you have a video in a certain format, I’d recommend Miro Video Converter to convert it to the other optimal formats as well.

How to do it

Let’s look at a complete example, taken from the included Video JS demo package, of how to include a video in a web page and use the native HTML5 video support if existent, or otherwise use a fallback.

<link rel="stylesheet" href="video-js.css" type="text/css" media="screen" title="Video JS">

<script src="video.js" type="text/javascript" charset="utf-8"></script>	

<!-- Begin VideoJS -->
<div class="video-js-box">
	<!-- Using the Video for Everybody Embed Code http://camendesign.com/code/video_for_everybody -->
	<video class="video-js" width="640" height="264" controls="controls" preload="auto" poster="http://video-js.zencoder.com/oceans-clip.png">
		<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
		<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm; codecs="vp8, vorbis"' />
		<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg; codecs="theora, vorbis"' />

		<!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. -->
		<object class="vjs-flash-fallback" width="640" height="264" type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
			<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
			<param name="allowfullscreen" value="true" />
			<param name="flashvars" value='config={"playlist":["http://video-js.zencoder.com/oceans-clip.png", {"url": "http://video-js.zencoder.com/oceans-clip.mp4","autoPlay":false,"autoBuffering":true}]}' />
			<!-- Image Fallback. Typically the same as the poster image. -->
			<img src="http://video-js.zencoder.com/oceans-clip.png" width="640" height="264" alt="Poster Image" title="No video playback capabilities." />
		</object>
	</video>

	<!-- Download links provided for devices that can't play video in the browser. -->
	<p class="vjs-no-video">
		<strong>Download Video:</strong>
		<a href="http://video-js.zencoder.com/oceans-clip.mp4">MP4</a>,
		<a href="http://video-js.zencoder.com/oceans-clip.webm">WebM</a>,
		<a href="http://video-js.zencoder.com/oceans-clip.ogv">Ogg</a><br>
		<!-- Support VideoJS by keeping this link. -->
		<a href="http://videojs.com">HTML5 Video Player</a> by VideoJS
	</p>
</div>
<!-- End VideoJS -->

Then, all you need to do is trigger the script when the DOM is ready:

	VideoJS.setupAllWhenReady();

If you want to, there are also some settings for the JavaScript:

VideoJS.setupAllWhenReady({
	controlsBelow: false, // Display control bar below video instead of in front of
	controlsHiding: true, // Hide controls when mouse is not over the video
	defaultVolume: 0.85, // Will be overridden by user's last volume if available
	flashVersion: 9, // Required flash version for fallback
	linksHiding: true // Hide download links when video is supported
});

Note: as you can see in the HTML code above, for the Flash fallback there’s a reference to Flowplayer to create a container to the video file and play it. Your mileage may vary, but you might need to download Flowplayer locally to the rest of your code to get it to work (alternatively use another Flash video player container).

Skinning capabilities

There are also a number of skins for Video JS available where you can make it look like other video web services on the web, or you can adapt it to match your own desired design.

Subtitles support

There is supposedly support for subtitles as well: if you add the attribute data-subtitles="demo-subtitles.srt" to the video element, it should display subtitles (I’ve tried adding this attribute in the included demo package, and currently it’s not working for me).

Web browser, device and format support

Video JS offers HTML5 video support for these web browsers:

  • Firefox
  • Google Chrome
  • Safari
  • Internet Explorer 9

complemented by fallback support for IE6 – IE8.

The supported video formats are:

  • WebM
  • Ogg Theora
  • H.264

Supported devices are:

  • iPhone
  • iPad
  • Android

Video for everybody

I think solutions like these are great, and exactly what progressive enhancement is about. So, unless DRM is vital for you, and you want to use HTML5 video right now, this is a great option!

10 Comments

  • Florent V. says:

    Video JS is nice, but the HTML code is scary. I’m more interested in solutions where you just write a VIDEO tag (with simple fallback content such as a download link), and the JS builds—sensibly—on top of that.

  • Robert Nyman says:

    Florent,

    The code is scary, but I think it’s a matter of making it work for everyone in comparison to neat code. But yes, definitely, no fallbacks and just download links is an option as well – it’s up to you.

  • alexander farkas says:

    @Florent
    You can give jme a try. It also supports using an object-tag inside of your video, but this isn’t necessary.

    It also gives you the freedom to define the structure of your control-elements / control bar and adds WAI-ARIA, if you didn’t used semantic markup. There is also a simple subtitle-plugin and you can also style the flash-fallback.

  • Pomeh says:

    I don’t like the “setupAllWhenReady”. What if I have two videos no my page and only want to start one ? The documentation is very poor, only one example “Getting Started”, that’s pretty bad because the library looks nice :(

    About subtitles, it seems like video.js support track tag in the video element,
    have a look. This lead to something like :

    <video>
    <source src="oceans-clip.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
    <source src="oceans-clip.webm" type='video/webm; codecs="vp8, vorbis"' />
    <source src="oceans-clip.ogv" type='video/ogg; codecs="theora, vorbis"' />
    <track kind="subtitles" src="path-to-your-file.srt" />
    </video>

    Also, video.js can work like a jQuery plugin. And this is not in the documentation, too bad :(

  • Robert Nyman says:

    alexander,

    Great, thanks for the tip!

    Pomeh,

    I agree that documentation is sparse, and I hope that will improve.
    Interesting about the track element; I tried it with the demo package, but no luck…

  • Joshua Web says:

    Very detailed post, especially the fallbacks. i apprecite you sharing this method, HTML5 can be a pain for us flash type folks :/

  • Robert Nyman says:

    Joshua,

    Glad it was helpful for you!

  • […] For now, and some considerable future, we will have to offer more than one format. Simple as that. A good approach for that is the one I described in Delivering HTML5 video and fallback support with the help of Video JS. […]

  • Karoon says:

    Ok I feel like I’m doing all of the right things, replacing my videos mp4, webm, and ogv but it is just not working in firefox for me. It keeps loading and loading and not playing. I have no idea what the problem is can someone post the code showing where items need to be replaced (I must be missing something)

  • Robert Nyman says:

    Karoon,

    I recommend downloading their demo to see that it works first, and then change things from there.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>