How to Get Video Thumbnails with Javascript

It is possible to get the thumbnail of a video at a specified duration using <canvas> and <video> elements. The basic process to implement this would be to :

  1. Use a <video> element to load the video. The source of the video can come from your server, or through a <input type="file"> (assuming the user is uploading the video).
  2. Wait for the video metadata to load. This is important because only after the video metadata is loaded, we can get the video dimensions and play the video (or seek to a specified duration).
  3. Place a hidden <canvas> element on the page. This <canvas> will hold the specified image from the video. We can then get the image from the canvas.

Demo

Click on the button below to select a video file :

Seek to seconds Download Video Thumbnail

Download Codes

The codes are written in pure Javascript, and are quite commented. The main highlights of the code are explained below.

HTML Involved

<div id="video-demo-container">
    <button id="upload-button">Select MP4 Video</button> 
    <input type="file" id="file-input" accept="video/mp4" />
    <video id="video-element" controls>
        <source type="video/mp4">
    </video>
    <canvas id="canvas-element"></canvas>
    <div id="thumbnail-container">
         Seek to <select id="set-video-seconds"></select> seconds <a id="download-link" href="#">Download Thumbnail</a>
    </div>
</div>

Using the Object URL as the <source> of the <video> Element

After user selects the video, the video has to shown as a <video> element on the HTML page. To set the source of this element, you can use the Object URL of the video. An Object URL is a local URL of the video constructed by the browser.

// On selecting a video file
document.querySelector("#file-input").addEventListener('change', function() {
    // Set object URL as the video <source>
    document.querySelector("#video-element source").setAttribute('src', URL.createObjectURL(document.querySelector("#file-input").files[0]));
});

Waiting for the Video Metadata to Load

The dimensions (width / height) of the generated thumbnail will depend on the dimensions of the <canvas> element. The dimensions of the <canvas> element will in turn depend on the dimensions of the video.

Please note that dimensions of video refers to the actual video, and not the CSS dimensions of the <video> element.

To get the dimensions of the video, you need to wait for the video metadata to load. This can be done through the loadedmetadata event.

var _VIDEO = document.querySelector("#video-element"),
    _CANVAS = document.querySelector("#canvas-element");

// Video metadata is loaded
_VIDEO.addEventListener('loadedmetadata', function() {
    // Set canvas dimensions same as video dimensions
    _CANVAS.width = _VIDEO.videoWidth;
    _CANVAS.height = _VIDEO.videoHeight;
});

Waiting for the Video Position to Change

You can change the current position of the playback through the currentTime property of the video element. However the change in playback happens asynchronously. You can wait for it to happen through the timeupdate event.

// Video playback position is changed
document.querySelector("#video-element").addEventListener('timeupdate', function() {
    // You are now ready to grab the thumbnail from the <canvas> element
});

Getting the Image from the Canvas

After you have decided to take the thumbnail of the current video frame, you can draw the current video frame in the canvas element. After that you can save the base-64 data of the canvas as an image.

var _VIDEO = document.querySelector("#video-element"),
    _CANVAS = document.querySelector("#canvas-element"),
    _CANVAS_CTX = _CANVAS.getContext("2d");

// Placing the current frame image of the video in the canvas
_CANVAS_CTX.drawImage(_VIDEO, 0, 0, _VIDEO.videoWidth, _VIDEO.videoHeight);

// Setting parameters of the download link
document.querySelector("#download-link").setAttribute('href', _CANVAS.toDataURL());
document.querySelector("#download-link").setAttribute('download', 'thumbnail.png');