Detect Supported Video Formats with JavaScript
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) {
// Allow user to create shortcuts, i.e. just "webm"
const 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"'
};
const 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:
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!
![5 More HTML5 APIs You Didn’t Know Existed]()
The HTML5 revolution has provided us some awesome JavaScript and HTML APIs. Some are APIs we knew we've needed for years, others are cutting edge mobile and desktop helpers. Regardless of API strength or purpose, anything to help us better do our job is a...
![I’m an Impostor]()
This is the hardest thing I've ever had to write, much less admit to myself. I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life. All of those feelings were very...
![Fx.Rotate: Animated Element Rotation with MooTools]()
I was recently perusing the MooTools Forge and I saw a neat little plugin that allows for static element rotation: Fx.Rotate. Fx.Rotate is an extension of MooTools' native Fx class and rotates the element via CSS within each A-grade browser it...
![spellcheck Attribute]()
Many useful attributes have been provided to web developers recently: download, placeholder, autofocus, and more. One helpful older attribute is the spellcheck attribute which allows developers to control an elements ability to be spell checked or subject to grammar checks. Simple enough, right?
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?
hls returns false everywhere, except Edge. But works everywhere except IE…
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?
Am I missing something?
function supportsVideoType(type) { let video; // <-- this is a local variable // 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) { // <--videowill always beundefined, so!videowill always be true video = document.createElement('video') } return video.canPlayType(formats[type] || type); }