How to detect supported video formats for the HTML5 video tag?

I am making an application in HTML5 using the video tag, in the application the user chooses a video file and I play that file. This all happens locally because I only link to that file in the user's machine.

I want to allow only formats the browser can play to be played in my application, and to show an error for unsupported formats. The problem is that different browsers can play different formats.

I know I can check for the browser and match it with the formats I know it can play, but what if the browser updates to support another format? I'll have to update my application with the new information and meanwhile users won't be able to play supported formats. Is there a way to check just for the supported video formats?


Solution 1:

You can check codecs for different video types with HTMLVideoElement.prototype.canPlayType. There is also a great HTML5 feature detection library, Modernizr.

var testEl = document.createElement( "video" ),
    mpeg4, h264, ogg, webm;
if ( testEl.canPlayType ) {
    // Check for MPEG-4 support
    mpeg4 = "" !== testEl.canPlayType( 'video/mp4; codecs="mp4v.20.8"' );

    // Check for h264 support
    h264 = "" !== ( testEl.canPlayType( 'video/mp4; codecs="avc1.42E01E"' )
        || testEl.canPlayType( 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) );

    // Check for Ogg support
    ogg = "" !== testEl.canPlayType( 'video/ogg; codecs="theora"' );

    // Check for Webm support
    webm = "" !== testEl.canPlayType( 'video/webm; codecs="vp8, vorbis"' );
}

Solution 2:

I'd recommend you use something like http://videojs.com/, they use a Flash fallback and their syntax will give you the correct order of the formats that you should use for all browsers.

It goes like this:

<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>

If the browser doesn't understand MP4, it goes to WebM, if it doesn't it goes to OGG, if it doesn't understand it, it goes to the Flash fallback.

Think of it like font-family declarations in CSS.