HTML5 video for retina displays
Recently I came across a question on Stack Overflow where a user wanted to serve a high resolution video to devices that supported retina displays. I had half a solution.
I guessed that the user hadn’t heard of the media
attribute of the source
element, which allows you to specify different sources providing a certain media query is met. I wrote about this a while back in an article on responsive HTML5 video.
This is only half the solution though, as we also need a media query that actually tells us that a device/browser has a retina display. I didn’t know of one and posted the question in my answer to the same Stack Overflow question linked to above.
Paul D. Waite promptly replied, bringing min-device-pixel-ratio
to my attention.
As Chris Coyier’s article shows, a value of 2 matches a retina device, so we can specify a retina video like this:
<video controls>
<source type='video/mp4' src='video-high-res.mp4' media='(min-device-pixel-ratio:2)'>
<source type='video/webm' src='video-high-res.webm' media='(min-device-pixel-ratio:2)'>
<source type='video/mp4' src='video.mp4'>
<source type='video/webm' src='video.webm'>
</video>
Of course as the article points out, prefixed versions are needed and the media query can be tweaked even further to provide high-res but smaller dimensioned videos to device with different screen sizes. A more complete example, using vendor prefixes, might look something like this:
<video controls>
<source type='video/mp4' src='video-high-res.mp4' media='(min-device-pixel-ratio:2), (-webkit-min-device-pixel-ratio:2), (min--moz-device-pixel-ratio:2), (-o-min-device-pixel-ratio:2)'>
<source type='video/webm' src='video-high-res.webm' media='(min-device-pixel-ratio:2), (-webkit-min-device-pixel-ratio:2), (min--moz-device-pixel-ratio:2), (-o-min-device-pixel-ratio:2)'>
<source type='video/mp4' src='video.mp4'>
<source type='video/webm' src='video.webm'>
</video>
Except it doesn’t actually work.
The devices I tested on always fell through to the source
element that didn’t have any media query set. Removing the source that had no media query set caused the “retina” source to play fine, so the media query value itself wasn’t what was causing it to be skipped, it just appeared to favour the source that had no media query.
So I decided to set the media
attribute on the other source
element, and to use max-device-pixel-ratio
(and its prefixed versions), set to a value of 1:
<video controls>
<source type='video/mp4' src='video-high-res.mp4' media='(min-device-pixel-ratio:2), (-webkit-min-device-pixel-ratio:2), (min--moz-device-pixel-ratio:2), (-o-min-device-pixel-ratio:2)'>
<source type='video/webm' src='video-high-res.webm' media='(min-device-pixel-ratio:2), (-webkit-min-device-pixel-ratio:2), (min--moz-device-pixel-ratio:2), (-o-min-device-pixel-ratio:2)'>
<source type='video/mp4' src='video.mp4' media='(max-device-pixel-ratio:1), (-webkit-max-device-pixel-ratio:1), (max--moz-device-pixel-ratio:1), (-o-max-device-pixel-ratio:1)'>
<source type='video/webm' src='video.webm' media='(max-device-pixel-ratio:1), (-webkit-max-device-pixel-ratio:1), (max--moz-device-pixel-ratio:1), (-o-max-device-pixel-ratio:1)'>
</video>
It was this combination (not strenously tested!) that actually worked.
Yet another use for the media
attribute and another reason why it should stay around!