Detect Supported Video Formats with JavaScript

By  on  
Detect Video Playback

Over the past few years we've been seeing new audio, video, and image formats take shape to challenge the legacy formats that we've used since the web's inception.  This is a great development as we have more processing power and better compression algorithms have been developed, leading to faster load times and rendering.  Hooray for speed!

The problem:  as with every other features added to the browser, some browsers get media format support faster than others, and some browsers refuse to support given formats.  Simply put:  we now need to do feature detection on media, something we've not traditionally had to do.  A while back I posted about how you can detect WEBP support in the browser and now I'd like to show you how to detect supported video formats -- it's easier than you think!

HTMLVideoElement.prototype.canPlayType

canPlayType is the secret to detecting video format support in the browser.  To use this method you must first create a <video> element instance:

const video = document.createElement('video');

You then call canPlayType, passing in the format's MIME type and additional details as needed:

video.canPlayType('video/webm; codecs="vp8, vorbis"'); // "probably"

There are three possible results from canPlayType:

  • "probably" : The media type appears to be playable
  • "maybe": Cannot tell if the media type is playable without playing it
  • "": The media type is not playable

Format Detection Function

Modernizr includes a small function to detect video format support; I've taken a moment to take that logic and create my own function for general purpose use without Modernizr:

function supportsVideoType(type) {
  let video;

  // Allow user to create shortcuts, i.e. just "webm"
  let formats = {
    ogg: 'video/ogg; codecs="theora"',
    h264: 'video/mp4; codecs="avc1.42E01E"',
    webm: 'video/webm; codecs="vp8, vorbis"',
    vp9: 'video/webm; codecs="vp9"',
    hls: 'application/x-mpegURL; codecs="avc1.42E01E"'
  };

  if(!video) {
    video = document.createElement('video')
  }

  return video.canPlayType(formats[type] || type);
}

// Usage
if(supportsVideoType('webm') === "probably") {
  // Set the video to webm
}
else {
  // Set the video to mpeg or mp4
}

I use feature detection function efficiency to only create one element and simply return the result if called more than once.  Using this function today, Chrome reports the following:

Detect Video Playback

The canPlayType method allowed you to feature detect the best compression and supported formats and server them to your users, thus making the most of your browser capabilities.  Get aggressive with your media formats to make your site as quick as possible!

Recent Features

  • By
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

  • By
    Animated 3D Flipping Menu with CSS

    CSS animations aren't just for basic fades or sliding elements anymore -- CSS animations are capable of much more.  I've showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet...

Incredible Demos

  • By
    Vibration API

    Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in...

  • By
    Multiple Background CSS Animations

    CSS background animation has been a hot topic for a long time, mostly because they look pretty sweet and don't require additional elements.  I was recently asked if it was possible to have multiple background animations on a given element and the answer is yes...with...

Discussion

  1. Radek Havelka

    Thank you for this article and info, but I am sorry, this is insane. WTF MAYBE, PROBABLY means??? Why not TRUE, FALSE, null or whatever similar?

  2. Daniel

    hls returns false everywhere, except Edge. But works everywhere except IE…

  3. Fernando Valle

    This is a great tip! Does anyone know what the proper MIME type would be for a .mov file with HEVC/h.265 encoding for safari?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!