javascript - 将 context.drawImage() 与 MediaStream 结合使用

标签 javascript reactjs canvas redux webrtc

我是 React 新手,正在构建一个从 MediaStream 获取屏幕抓取的应用程序。根据我所看到的,最好的方法是使用 context.drawImage() 将其绘制到 Canvas 元素上。方法,传入 HTMLVideoElement 作为参数。我的 Action 创建器如下所示:

const RecordImage = function(video, canvas, encoder) {
   if(!encoder) {
       encoder = new GifReadWrite.Encoder()
       encoder.setRepeat(0)
       encoder.setDelay(100)
       encoder.start()
   }
   const context = canvas.getContext('2d')
   context.drawImage(video, 0, 0)
   encoder.addFrame(context)
   return {
       type:       RECORD_IMAGE,
       payload:    encoder
   }
}

这在过去有效,因为 RecordImage 操作是从容纳 <video /> 的同一组件调用的。和<canvas />元素,我可以像这样传递它们:

takePic(event) {
    event.preventDefault()
    this.props.RecordImage(this.video, this.canvas, this.props.encoder)
}
...
render() {
    return (
        <div>
            <video 
                ref         = { video => this.video = video } 
                width       = { this.props.constraints.video.width } 
                height      = { this.props.constraints.video.height } 
                autoPlay    = "true" 
            />
            <canvas 
                ref         = { canvas => this.canvas = canvas }
                width       = { this.props.constraints.video.width } 
                height      = { this.props.constraints.video.height } 
            />
            <button onClick = { this.takePic }>Take Picture</button>
        </div>
    )
}

但是,我想将“拍照”按钮放置在不同的组件中。这是一个问题,因为现在我不知道如何访问 <video /><canvas />来自同级组件的元素。通常我会将所需的参数存储为状态的一部分,但是 drawImage()方法需要使用 HTML 元素本身。我听说在状态中存储 DOM 元素是个坏主意,那么最好的方法是什么?

最佳答案

在 React 中,可以直接调用组件之一上的函数。
您可以在视频组件中添加一个返回视频元素的“getPicture”函数吗?

您的视频组件:

getPicture() {
    return this.video
}
...
render() {
    return (
        <div>
            <video 
                ref         = { video => this.video = video } 
                width       = { this.props.constraints.video.width } 
                height      = { this.props.constraints.video.height } 
                autoPlay    = "true" 
            />
        </div>
    )
}

图片按钮组件可能看起来像这样:

takePic() {
    const element = this.props.getPic
    const encoder = new GifReadWrite.Encoder()
   encoder.setRepeat(0)
   encoder.setDelay(100)
   encoder.start()

   const canvas = document.createElement("canvas") 
   canvas.width = element.offsetWidth
   canvas.height = element.offsetHeight
   canvas.drawImage(video, 0, 0)
   encoder.addFrame(context)
   return {
       type:       RECORD_IMAGE,
       payload:    encoder
   }
}

...
render() {
    return (
        <button onClick = { () => this.takePic() }>Take Picture</button>
    )
}

然后是一个父组件来绑定(bind)按钮和视频组件:

getPicture() {
    return this.video.getPicture()
}
...
render() {
    return (
        <div>
            <VideoElement ref="video => this.video = video"/>
            <TakePictureButton getPic="() => this.getPicture()" />
        </div>
    )
}

免责声明:我不确定绘图函数是如何工作的,但你明白了

关于javascript - 将 context.drawImage() 与 MediaStream 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48615934/

相关文章:

javascript - 获取从 php 返回到 jquery 的任何 div 及其子元素的 id

javascript - 使用三元运算符有条件地显示 AngularJS 模板中的内容

reactjs - React Monaco Editor 没有语法高亮

javascript - 如何使用模拟 api 调用测试 React 组件

Javascript - 在 Canvas 上平铺多个图像

javascript - 如何检查双 v-for 和 if 都在则更改样式

javascript - 如何将数据API放入Ant Design Cascader中?

javascript - 在 JavaScript 中为 for 循环设置动画( Canvas )

javascript - 在跟随鼠标指针的图像上制作轴引导线

javascript - 仅展开父级内的子 Div