While many web developers have focused on the progress of the <picture> element for adaptive images, the very similar capabilities <source> tag for HTML5 video are largely unknown, and often overlooked. If your responsive site uses self-hosted video, customizing your movies for different screen sizes not only optimizes visitor's viewing experience, but can also add significant savings in bandwidth costs.

Crafting The Queries

First, you’ll need to compress at least two versions of the same video in different sizes: in the example above, I’ve created a 720 × 1280 HD version and a 640 × 360 SD copy. Naturally, you would also have to save these videos in at least two different formats, to cover all browser requirements.

The <video> tag is inserted into the page as usual. Both versions of the movie are added inside it, with media queries written inline to distinguish between the sources:

<video controls>
	<source src="the-sky-is-calling-large.mp4" media="screen and (min-width:800px)">
	<source src="the-sky-is-calling-large.webm" media="screen and (min-width:800px)">
	<source src="the-sky-is-calling-small.mp4" media="screen and (max-width:799px)">
	<source src="the-sky-is-calling-small.webm" media="screen and (max-width:799px)">
</video>

Of course none of this is terribly useful unless the <video> element itself is responsive. I’ve covered that in a previous article; the CSS is the same as that applied to responsive bitmap images:

video { width: 80%; }
video source { width: 100%; height: auto; }

Improving The Queries

While this works, it only does so on initial load: that is, when the HTML page is first visited, the appropriate video is used for the current window size. This selection will be in effect thereafter, no matter how the window is resized. The choice of video isn’t reconsidered unless the page itself is reloaded.

To that end, a better solution is to use a media query to inspect the width of the device, rather than the current window, and choose the appropriate video based on the result:

<video controls>
	<source src="the-sky-is-calling-large.mp4" media="screen and (min-device-width:801px)">
	<source src="the-sky-is-calling-large.webm" media="screen and (min-device-width:801px)">
	<source src="the-sky-is-calling-small.mp4" media="screen and (max-device-width:800px)">
	<source src="the-sky-is-calling-small.webm" media="screen and (max-device-width:800px)">
</video>

These new rules set up the following conditions:

  • If the physical screen of the device is no more than 800 pixels wide, then it will receive the small video version.
  • If the physical device has a horizontal resolution of 801 pixels or greater, it will receive the large video, without regard to the initial browser window size.

In theory it would be possible to use JavaScript matchMedia conditions to switch between versions as the browser window is resized, but I would consider the potential interruptions in the video stream to make the effort valueless.

Conclusion

While it takes a little more work to get there, the potential savings and improved user experience from adding inline media queries to video makes the effort very worthwhile. Right now, all modern browsers support these techniques; over time, I would expect that HTML5 and video codecs will integrate adaptive playback algorithms into themselves, gaining the ability to stream different resolution of the same video from a single source in response to both screen size, network performance, and device capability. For now, this solution is what we have, and it’s not a bad one.

Video by Nicholas Sugai, licensed under Creative Commons

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.