How to work with HTML video

Move over YouTube... with the <video> element and a little JavaScript, you can start to create your own video site. The video element is fairly straightforward to use, but the real power comes when you combine it with JavaScript, which gives you a high level of control over the player’s behaviour. 

In this tutorial, we cover the basic setup of a video, selecting files to play back, and generating thumbnails. Not your thing? Use a website builder to create a site with no code, and explore your web hosting options.

01. Create a basic page

Let’s start with an HTML page outline. We’ll need a simple div structure, some CSS for styling and, most critically, a script file. You’ll notice that the video tag is empty right now, so will do nothing when you load the page. However, we give it an id so we can control it with JavaScript.

<!DOCTYPE html>
<html>
  <head>
  <meta charset='utf-8'/>
  <title>My HTML Video Player</title>
  <link rel='stylesheet' href='custom.css'/>
  <script src="player.js"></script>
  </head>
  <body>
  <div id="title">
  <h1>Welcome to my video library!</h1>
Scroll through the videos below and click the one you want to play.
  </div>
  <div id="thumbnail-container">
  </div>
  <div id="player-container">
  <video id="player">
  </video>
  <div id="controls">
  </div>
  </div>
  </body>
  </html>

02. Style the page

Next, we’ll start adding styling to the page. Before we try to do anything too clever, let’s start by adding basic styling to a couple of our div elements so things look a little more respectable.

body {
  background-color: #cccccc;
  font-family: sans-serif;
}
#player-container {
  margin-left: auto;
  margin-right: auto;
  width: 640px;
  height: 480px;
  background-color: #538c99;
  border-radius: 20px;
}
#title {
  margin-left: auto;
  margin-right: auto;
  width: 640px;
  text-align: center;
  padding-top: 30px;
  padding-bottom: 50px;
  background-color: #538c99;
  color: #333333;
  border-radius: 20px; }

03. Add more styling

Things become a little more interesting when we come to style the thumbnail-container div. We’re going to fill this with img elements, which will be thumbnails generated from our videos. Therefore, we want it to display a horizontal scrollbar if we have more thumbnails than it can show at once. We can do this using the overflow-x property.

#thumbnail-container {
  background-color: #cccccc;
  margin-top: 30px;
  margin-left: auto;
  margin-right: auto;
  width: 640px;
  height: 120px;
  overflow-x: scroll;
  overflow-y: hidden;
  white-space: nowrap;
  border-radius: 20px; }

04. Size the video player appropriately

There’s one more bit of styling we need to do. As it is, when we start playing videos, they’ll display at whatever their native resolution is. This isn’t going to look good on the page. Let’s style the video element to determine how big it should be. If we set its width and height to 100%, it’ll just fill its containing div.

video {
  width: 100%;
  height: 100%; }

05. Set up the script

It’s time to get down to the JavaScript. Let’s prepare a list of video files in an array for it to work with (we’ll hard-code for now, but you could try configuring it to retrieve via JSON from an HTTP service).

We’ll also define a couple of variables which we’ll use later on: ‘player’ will be the video element; ‘playerSource’ will be a newly created source element that will become a child of the player object later on, and point to source files. We’ll also plan to hook into a DOMContentLoaded event to make sure the script waits for the page to load before kicking into action.

var videoFiles = ["1.mp4", "2.mp4", "3.mp4", "4.mp4", "5.mp4"];
var player;
var playerSource = document.createElement("source");
document.addEventListener("DOMContentLoaded",function() { initialise(); }, false);

Note that video playback in the browser relies on the presence of a codec that can read the video format you’re using. To ensure your video works cross-browser, the safest bet is MP4 files using the H.264 codec.

06. Generate a thumbnail

Next let’s create a function that will generate an image thumbnail from a video file back the videos up in cloud storage). We want this to take in a video object and return an image object. Internally, the way we will achieve this is using HTML canvas.

function generateThumbnail(video) {
  var canvas = document.createElement("canvas");
  var container = document.getElementById("thumbnail-container");
  var width = container.clientWidth;
  var height = container.clientHeight;
  canvas.width = (width / 3);
  canvas.height = height;
  canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
  var image = document.createElement("img");
  image.src = canvas.toDataURL();
  return image; }

07. Automatically generate thumbnails as videos are loaded

Now we can take the generateThumbnail function and use it on each of the video files in our list. Let’s do this by implementing the initialise() function. This function will add the playerSource object as a child of the video element, then iterate through every file in the list, load it into a temporary video object, and once loaded, generate a thumbnail and add it to the thumbnail container.

function initialise() {
  player = document.getElementById("player");
  player.appendChild(playerSource);
  player.controls = false;
  videoFiles.forEach(function(file) {
  var thumbSource = document.createElement("source");
  thumbSource.src = file;
  var thumbVideo = document.createElement("video");
  thumbVideo.addEventListener("loadeddata", function() {
  var container = document.getElementById("thumbnail-container")
  var image = generateThumbnail(thumbVideo);
  container.appendChild(image);
  }, false);
  thumbVideo.appendChild(thumbSource);
  }); }

There’s something missing, though. Our thumbnails show up in the container, but none of them are clickable. We need to wrap the images in an <a> element, which needs to execute some JavaScript when clicked. Let’s adjust the function hooked to the loadeddata event to create the links as well, instead of just img elements.

thumbVideo.addEventListener("loadeddata", function() {
  var container = document.getElementById("thumbnail-container")
  var image = generateThumbnail(thumbVideo);
  var link = document.createElement("a");
  link.href = "javascript:play(\"" + thumbSource.src + "\")";
  link.appendChild(image);
  container.appendChild(link);
  }, 
false);

09. Play a video

Now we are generating thumbnails with clickable links, which are set up to invoke play(thumbSource.src), where thumbSource.src points to the filename of the relevant video file. All that remains is to implement the play function to set playerSource (which you’ll recall we linked to the video player element) to point to the correct file and kick off playback.

function play(url) 
{
  playerSource.src = url;
  player.controls = true;
  player.load();
  player.play(); 
}

This article originally appeared in issue 266 of Web Designer, the creative web design magazine – offering expert tutorials, cutting-edge trends and free resources. Buy issue 266 here or subscribe to Web Designer here.

Related articles:

Thank you for reading 5 articles this month* Join now for unlimited access

Enjoy your first month for just £1 / $1 / €1

*Read 5 free articles per month without a subscription

Join now for unlimited access

Try first month for just £1 / $1 / €1

Simon Jones

Simon Jones is a technology leader with experience managing product and engineering teams of up to 200 staff, both at startups and large corporates. He is a proficient full-stack developer, in particular with Go & React + TypeScript. He now works at Facebook in London. Formerly CTO at Norwegian VC-backed startup Just, and Engineering Director at Barclays and American Express.