React:以特定帧速率渲染画布

时间:2018-01-05 19:51:25

标签: javascript html reactjs

对React来说很新,试图理解它的基础知识。 我想在播放时将视频内容呈现给画布。我的解决方案会导致溢出。我该如何管理这样的递归调用?

import React, {Component} from 'react';


class VideoPlayer extends React.Component {

    componentDidMount() {
        this.context = this.refs.canvas.getContext('2d');
    }

    play() {
        if (this.refs.video.paused) {
            this.refs.video.play();
            this.updateCanvas();
        } else {
            this.refs.video.pause();
        }
    }

    updateCanvas() {
        if (this.refs.video.paused || this.refs.video.ended) {
            return;
        }

        let fps = 30;
        this.context.drawImage(this.refs.video, 0, 0, 400, 220);

        setTimeout(requestAnimationFrame(this.updateCanvas()), 1000 / fps);
    }

    render() {
        return (
            <div>
                <video width="400" ref="video" id="v">
                    <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
                </video>
                <canvas ref="canvas" width="400" height="220"></canvas>
                <br/>
                <button type="button" onClick={this.play.bind(this)}>Play</button>
            </div>

        );
    }
}

export default VideoPlayer;

1 个答案:

答案 0 :(得分:0)

如果您想定期拨打电话,最好使用SidePanelsetInterval而不是clearInterval。递归总是有点棘手,处理延迟会使整个方法更加棘手。

因此,当按下播放(并且视频尚未播放)时,该想法将成为setTimeout的编程,将当前视频帧复制到画布中,并以< em> n fps。返回的setInterval处理程序将保存到组件的状态。

再次按下播放(并且视频正在运行)时,将通过调用状态中保存的intervalclearInterval来清除间隔功能。

此外,为了处理我们让视频运行的情况,如果我们按下播放时interval处理程序设置为状态(并且视频尚未运行),那么我们只需要调用interval处理程序中存在clearInterval处理程序(如果您不这样做,每次视频运行到结束时,您将有未清除的间隔堆积=内存泄漏)。

为了获取当前视频帧的副本,我们还实现了一个非常基本的interval方法,并确保它绑定到组件的上下文

最后,我们获取副本的速率(即FPS)作为道具传递给组件。

grabFrame

有关工作示例,请参阅this CodeSandbox