15

I want to grab an image from a video based on the current time of the video upon button click. I'm currently using the video tag to play the video but have not seen any resource for grabbing an image from that.

<video
    id="video-player"
    class="video-player"
    width="640"
    controls="controls"
    muted=true>
    <source type="video/mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" id="mp4"></source>
    <source type="video/webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" id="webm"></source>
    <source type="video/ogg" src="http://media.w3.org/2010/05/sintel/trailer.ogv" id="ogv"></source>
    <p>Your user agent does not support the HTML5 Video element.</p>
</video>
Danson
  • 415
  • 1
  • 7
  • 16

2 Answers2

26

This can be done via canvas. Let's say you have a video

<video id="video" controls="controls">
  ....
</video>

You can do the following:

const video = document.getElementById("video");

const canvas = document.createElement("canvas");
// scale the canvas accordingly
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// draw the video at that frame
canvas.getContext('2d')
  .drawImage(video, 0, 0, canvas.width, canvas.height);
// convert it to a usable data URL
const dataURL = canvas.toDataURL();

You can then do whatever you want with dataURL, such as displaying it as an image:

var img = document.createElement("img");
img.src = dataURL;

Inspiration drawn from odetocode

Overcode
  • 4,074
  • 1
  • 21
  • 24
nolawi
  • 4,439
  • 6
  • 22
  • 45
13

Pure JS way with scale support:

/**
 * Takes a screenshot from video.
 * @param videoEl {Element} Video element
 * @param scale {Number} Screenshot scale (default = 1)
 * @returns {Element} Screenshot image element
 */
function getScreenshot(videoEl, scale) {
    scale = scale || 1;

    const canvas = document.createElement("canvas");
    canvas.width = videoEl.clientWidth * scale;
    canvas.height = videoEl.clientHeight * scale;
    canvas.getContext('2d').drawImage(videoEl, 0, 0, canvas.width, canvas.height);

    const image = new Image()
    image.src = canvas.toDataURL();
    return image;
}
Denis L
  • 3,209
  • 1
  • 25
  • 37