video转canvas, 并截图

示例

import * as React from 'react';
import mp4 from '!file-loader!@/a.mp4';

function save2file(canvas: HTMLCanvasElement) {
    var a = document.createElement('a');
    try {
        a.href = canvas.toDataURL(); // 视频源必须同源,否则无法截屏,并抛出安全异常
        a.download = 'video_snaphost.png';
        a.click();
    } catch (err) {
        alert(err.toString());
    }
}

export default class extends React.Component {
    video = React.createRef<HTMLVideoElement>();
    canvas = React.createRef<HTMLCanvasElement>();
    play = false;

    start() {
        var video = this.video.current;
        video.play();
        var canvas = this.canvas.current;

        var ctx = canvas.getContext('2d');

        this.play = true;
        var thiz = this;
        requestAnimationFrame(function onDraw() {
            console.log(canvas.width, canvas.height); // 确保等于parentElement.clientW/H
            ctx.drawImage(
                video, // image source
                0, 0, // source position
                video.videoWidth, video.videoHeight, // copy scale
                0, 0, // draw position
                canvas.width, canvas.height, // draw scale
                // X 不要以为这样就OK了
                // canvas.parentElement.clientWidth, canvas.parentElement.clientHeight, // draw scale
            );
            thiz.play && requestAnimationFrame(onDraw);
        });
    }

    screenshot() {
        var video = this.video.current;
        var canvas = this.canvas.current;

        this.play = false;
        video.pause();
        
        setTimeout(() => { // 模拟延时曝光
            save2file(canvas);
            video.play();
            this.start();
        }, 600);
    }

    render() {
        return (
            <div>
                <div style={{ display: 'none',  '400px', height: 'auto', background: 'black' }}>
                    <video autoPlay muted controls controlsList="nodownload nofullscreen"
                        style={{  '100%', height: '100%' }}
                        ref={this.video} src={'http://localhost:12308/a.mp4' || mp4}>
                    </video>
                </div>

                <div style={{  '1400px', height: '800px', background: 'black' }}>
                    <canvas ref={this.canvas} style={{  '100%', height: '100%' }}></canvas>
                </div>

                <div>
                    <button onClick={ev => this.start()}>play in canvas</button>
                </div>

                <div>
                    <button onClick={ev => this.screenshot()}>screenshot</button>
                </div>
            </div>
        );
    }

    componentDidMount() {
        // 这里保证canvas的width和height属性有值,css只起到拉伸的作用,画布大小有其默认值
        this.canvas.current.width = this.canvas.current.parentElement.clientWidth;
        this.canvas.current.height = this.canvas.current.parentElement.clientHeight;
        document.querySelector('button').click();
    }
};

END

原文地址:https://www.cnblogs.com/develon/p/14277725.html