JSFiddle - React, Tailwind, and code Playground

HTML

<video id="video" controls preload="none" width="640" poster="http://media.w3.org/2010/05/sintel/poster.png" onloadedmetadata="$(this).trigger('video_really_ready')">
        <source id='mp4' src="http://media.w3.org/2010/05/sintel/trailer.mp4" type='video/mp4' />
        <source id='webm' src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm'/>
        <source id='ogv' src="http://media.w3.org/2010/05/sintel/trailer.ogv" type='video/ogg' />
    </video>
    <br />
    
    <input type="button" id="capture" value="Capture" /> Press play, and then start capturing
    <div id="screen"></div>

JavaScript

var VideoSnapper = {
    
        /**
         * Capture screen as canvas
         * @param {HTMLElement} video element 
         * @param {Object} options = width of screen, height of screen, time to seek
         * @param {Function} handle function with canvas element in param
         */
        captureAsCanvas: function(video, options, handle) {
        
            // Create canvas and call handle function
            var callback = function() {
                // Create canvas
                var canvas = $('<canvas />').attr({
                    width: options.width,
                    height: options.height
                })[0];
                // Get context and draw screen on it
                canvas.getContext('2d').drawImage(video, 0, 0, options.width, options.height);
                // Seek video back if we have previous position 
                if (prevPos) {
                    // Unbind seeked event - against loop
                    $(video).unbind('seeked');
                    // Seek video to previous position
                    video.currentTime = prevPos;
                }
                // Call handle function (because of event)
                handle.call(this, canvas);    
            }

            // If we have time in options 
            if (options.time && !isNaN(parseInt(options.time))) {
                // Save previous (current) video position
                var prevPos = video.currentTime;
                // Seek to any other time
                video.currentTime = options.time;
                // Wait for seeked event
                $(video).bind('seeked', callback);              
                return;
            }
            
            // Otherwise callback with video context - just for compatibility with calling in the seeked event
            return callback.apply(video);
        }
};

$(function() {
    
        $('video').bind('video_really_ready', function() {
            var video = this;
           ...