对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;
答案 0 :(得分:0)
如果您想定期拨打电话,最好使用SidePanel
和setInterval
而不是clearInterval
。递归总是有点棘手,处理延迟会使整个方法更加棘手。
因此,当按下播放(并且视频尚未播放)时,该想法将成为setTimeout
的编程,将当前视频帧复制到画布中,并以< em> n fps。返回的setInterval
处理程序将保存到组件的状态。
再次按下播放(并且视频正在运行)时,将通过调用状态中保存的interval
值clearInterval
来清除间隔功能。
此外,为了处理我们让视频运行的情况,如果我们按下播放时interval
处理程序设置为状态(并且视频尚未运行),那么我们只需要调用interval
处理程序中存在clearInterval
处理程序(如果您不这样做,每次视频运行到结束时,您将有未清除的间隔堆积=内存泄漏)。
为了获取当前视频帧的副本,我们还实现了一个非常基本的interval
方法,并确保它绑定到组件的上下文
最后,我们获取副本的速率(即FPS)作为道具传递给组件。
grabFrame
有关工作示例,请参阅this CodeSandbox。