Using HTML5 Video with Canvas

Onur Şuyalçınkaya
Delivery Hero Tech Hub
3 min readJan 31, 2020

You’ve already learned a lot about the <video> element in my previous article “What I’ve Learned From Working With HTML5 Video Over A Month”, but did you know that the <video> and <canvas> elements would be a great choice to use together? In fact, the two elements are absolutely wondrous when you combine them! I’m going to show you a handy demo using these two elements, which I hope will prompt cool future projects from you.

Firstly, place the <video> and <canvas> elements in your HTML. Give your dimensions(width, height) to <canvas> according to your video. And of course, hide your video with the hidden attribute or “display: none” styling. Because <canvas> will do the trick for you ;)

Let’s go through one by one.

View

<canvas width="1280" height="720"></canvas>
<video
src="foo.mp4"
preload="auto"
autoplay
playsinline
webkit-playsinline
muted
hidden
>
</video>

We’re hiding the video element because we just want <canvas> to show the video, not <video> element itself.

Declarations

Let’s declare the variables that will be used.

const canvas = document.querySelector('canvas');
const video = document.querySelector('video');
const fps = 60;
const width = 1280;
const height = 720;
const canvasInterval = null;
  1. First, let’s get our <canvas> and <video> elements to use later.
  2. fps means frame per second. It’s important according to the video’s frame. You may want to use it as 24, or 30, or 60. It will be used for the interval’s millisecond value.
  3. width and height are the dimensions in pixels of the video. They will be given to the canvas element. If you do not specify them, <canvas> will take 300 for width and 150 for height as default which may break your view.
  4. I will use canvasInterval variable to set and clear an interval to make <canvas> follow and unfollow the <video> element.

Logic

Here is the magical part, with the whole code.

const canvas = document.querySelector('canvas');
const video = document.querySelector('video');
const fps = 60;
const width = 1280;
const height = 720;
const canvasInterval = null;
drawImage() {
canvas.getContext('2d', { alpha: false }).drawImage(video, 0, 0, width, height);
}
canvasInterval = window.setInterval(() => {
drawImage(video);
}, 1000 / fps);
video.onpause = function() {
clearInterval(canvasInterval);
};
video.onended = function() {
clearInterval(canvasInterval);
};
video.onplay = function() {
clearInterval(canvasInterval);
canvasInterval = window.setInterval(() => {
drawImage(video);
}, 1000 / fps);
};

drawImage() method draws the video onto the canvas.

video.onpause(), video.onended(), and video.onplay() methods are related to the performance issue. When the video paused or ended, we do not need to draw <video> onto the <canvas>, because you know, the frame is not changing after paused or ended. And when the <video> starts playing/resuming, <canvas> should start/resume drawing the <video> onto <canvas> as well.

If you know anyone that would benefit from this guide I would love if you recommended it to them. Thank you for following this article and reading through to the end, see you on another one…

Originally published at Onur Şuyalçınkaya Blog.

--

--