传递给video.addEventListener(“ play”)事件的函数未定义

时间:2018-11-23 14:04:19

标签: javascript reactjs canvas html5-canvas

我目前正在开发一个React组件,该组件需要将视频元素中的帧传递到画布元素上。

在视频正常播放的同时,画布上没有任何内容。我相信这是因为我所写的绘制框架的方法不在范围内,并且由于我坚持下一步尝试,将不胜感激关于替代方法的任何想法。

import React, { Component, Fragment } from 'react'

class Stream extends Component {
  constructor(props) {
    super(props);
    this.video = React.createRef();
    this.canvas = React.createRef();
    this.screen = React.createRef();

    this.drawFrame = this.drawFrame.bind(this);
  }

  drawFrame(video) {
    const screen = this.screen.current
    screen.height = 500
    screen.width = 500
    let context = screen.getContext('2d')
    context.drawImage(video, 0, 0, screen.width, screen.height)
    context.drawImage(video, 0, 0, screen.width, screen.height)
    requestAnimationFrame(this.drawFrame)
    console.log("Screen", screen)
  }

  componentDidMount() {
    // This code runs a video stream.
    const video = this.video.current
    navigator.mediaDevices.getUserMedia({ video: true, audio: false })
    .then(function(stream) {
        video.srcObject = stream
        video.play()
        // Says drawFrame is undefined if line below in uncommented.
        //video.addEventListener("play", this.drawFrame(video), false);
        console.log("Video is playing from component")
    })
    .catch(function(err) {
        console.log("An error occurred! " + err)
    })
  }

  componentDidUpdate() {}

  render() {
    return(
      <Fragment>
          <video
            ref={this.video}
            width="500"
            height="500"
          >Video stream is not available.</video>
          <canvas
            ref={this.screen}
            width="500"
            height="500"
          >Canvas is not available in this browser.</canvas>
          <canvas
            ref={this.canvas}
            width="500"
            height="500"
          >Canvas is not available in this browser.</canvas>
      </Fragment>
    )
  }
}

export default Stream

1 个答案:

答案 0 :(得分:2)

您丢失了this参考的上下文。只需在词汇上下文中使用arrow function

.then((stream) => ...

如果您不能使用箭头功能,请按旧方法进行操作,请关闭this并将其存储在其他变量中,然后使用它:

componentDidMount() {
    const _this = this;
    // This code runs a video stream.
    const video = this.video.current
    navigator.mediaDevices.getUserMedia({ video: true, audio: false })
    .then(function(stream) {
        video.srcObject = stream
        video.play()
        video.addEventListener("play", _this.drawFrame(video), false);
        console.log("Video is playing from component")
    })