High performance video for the web

High performance video for the web

5. Make the most of the video element

Duration: 5:00

A completed version of this section is in the step-02 folder.

In this codelab, we’ll be using open source video from The Blender Foundation.

The video element is a thing of simple beauty. Download, decode and play back video with a few lines of code.

Let’s get started!

Add a video element to index.html in your work folder:

<video autoplay controls src="video/bunny.webm">
  <p>Sorry! Your browser doesn't support the video element.</p>
</video>

Notice that the video element always has a closing </video> tag: it’s not ‘self-closing’. Any elements inside it (such as the paragraph in this example) will be displayed if the browser doesn’t support video.

Try it out in the browser: you should see a big white rabbit.

Time fragments

You can specify a start and end time by adding a fragment to the URL. This enables multiple views on the same video.

Try it out:

<video autoplay controls src="video/bunny.webm#t=25,26">
  <p>Sorry! Your browser doesn't support the video element.</p>
</video>

Video formats

What if you want to serve video to Safari users? Safari supports MP4 video but not WebM.

The source element

Use the source element to enable browsers to choose from multiple formats. MP4 and WebM cover all modern browsers, including all mobile browsers. Specify video sources in order of preference:

<video autoplay controls>
  <source src="video/bunny.webm" />
  <source src="video/bunny.mp4" />
  <p>Sorry! Your browser doesn't support the video element.</p>
</video>

Adding a type attribute to a source element enables the browser to select a video source without having to download part of the video to check:

<video autoplay controls>
  <source src="video/bunny.webm" type="video/webm" />
  <source src="video/bunny.mp4" type="video/mp4" />
  <p>Sorry! Your browser doesn't support the video element.</p>
</video>

Try it out!

The demo at simpl.info/video/notype has source elements without type attributes. Open the page in Safari from your own computer or phone and look at network activity from Web Inspector.

You’ll see that Safari has to download a little bit of metadata for the WebM file to ‘sniff’ the format. That requires one more resource request, and additional processing, which is not good anywhere, particularly on mobile.

Format support

Want to know what formats are supported by your browser?

Try the video canPlayType() method.

Add the following code to the main.js file in the jsdirectory in your workdirectory:

var videoElement = document.querySelector('video');
console.log('fubar', videoElement.canPlayType('fubar'));
console.log('webm', videoElement.canPlayType('video/webm'));
console.log('webm/vp8', videoElement.canPlayType('video/webm; codecs="vp8"'));

Take a look at the output from the DevTools console.

There are many factors that affect whether or not a browser can play a particular format, so the browser cannot give a definite yes or no answer to canPlayType(). Hence the maybe and probably values! An empty string means the container and codec combination is definitely not supported.

Video src

Want to know which source was actually chosen? Add this to your JavaScript:

console.log(videoElement.currentSrc);

Video size and display size

While you’re there, you can get the actual height and width of the video. That might be different from the dimensions of the video element — in the same way that images can be displayed bigger or smaller than their actual size. For this, you need to wait until the video metadata is loaded:

videoElement.onloadedmetadata = function() {
  console.log(this.videoWidth);
  console.log(this.videoHeight);
};

Thinking about display size and CSS, a simple technique for video is to specify a width and a max-width. That way you get a preferred size, but the video never overflows its container. Don’t specify a height: the browser will work that out automatically. That way you’ll keep the right aspect ratio. Much easier and less error prone than trying to calculate it manually!

Add the following to main.css in the work/css folder:

video {
  width: 640px;
  max-width: 100%;
}

The poster attribute

Last but not least, let’s add a poster image: an image displayed before playback, as soon as a video element is rendered.

There’s already a poster image in the work/images folder: poster.jpg. Add a poster attribute to the opening tag of the video element:

<video autoplay controls poster="images/poster.jpg">

Including a poster attribute gives viewers a meaningful idea of content without needing to download video or start playback. The only downside is that using a poster image incurs an additional file request, which consumes a little bit of bandwidth and requires rendering.

Learn more