首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将视频流javascript代码转换为React (ML5)

将视频流javascript代码转换为React (ML5)
EN

Stack Overflow用户
提问于 2019-02-03 07:13:30
回答 2查看 707关注 0票数 0

我尝试将ML5图像分类示例(Link)中的代码转换为我的React组件,如下所示:

代码语言:javascript
复制
class App extends Component {
  video = document.getElementById('video');

  state = {
    result :null
  }

  loop = (classifier) => {
    classifier.predict()
      .then(results => {
        this.setState({result: results[0].className});
        this.loop(classifier) // Call again to create a loop
      })
  }

  componentDidMount(){
    ml5.imageClassifier('MobileNet', this.video)
      .then(classifier => this.loop(classifier))

  }
  render() {

    navigator.mediaDevices.getUserMedia({ video: true })
      .then((stream) => {
        this.video.srcObject = stream;
        this.video.play();
      })

    return (
      <div className="App">
        <video id="video" width="640" height="480" autoplay></video>
      </div>
    );
  }
}

export default App;

然而,这并不起作用。错误消息显示Unhandled Rejection (TypeError): Cannot set property 'srcObject' of null

我可以想象video = document.getElementById('video');可能无法通过id获取元素。所以我试着

代码语言:javascript
复制
  class App extends Component {
  video_element = <video id="video" width="640" height="480" autoplay></video>;

  ...

  render() {
    ...
    return (
      <div className="App">
        {video_element}
      </div>
    );
  }
}

这也不起作用。我很困惑什么才是实现这个的正确方法?

感谢您的帮助,谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-06 06:08:15

我再次强调了一个略有不同的问题,而不是ref问题。

有一个巨大的问题,它导致可怕的闪烁和不断失败的承诺,因为一个异常……它是render方法中用户媒体的get!

请考虑这一点,每次设置状态时,组件都会重新呈现。你有一个不断更新组件状态的循环,而这个承诺总是失败。

您需要在挂载组件时获取用户介质:

代码语言:javascript
复制
componentDidMount() {
  navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {
    if (this.video.current) {
      this.video.current.srcObject = stream;
      this.video.current.play();
    }

    ml5.imageClassifier("MobileNet", this.video.current)
       .then(classifier => this.loop(classifier));
  });
}

这样一来,你的渲染方法就短多了:

代码语言:javascript
复制
render() {
  return (
    <div className="App">
      <video ref={this.video} id="video" width="640" height="480" autoPlay />
    </div>
  )
}
票数 1
EN

Stack Overflow用户

发布于 2019-02-03 07:50:22

在视频元素被实例化的时候,App元素还不存在,但是document.getElementById会运行,返回未定义的或空的。这就是为什么你会得到:

代码语言:javascript
复制
Cannot set property 'srcObject' of null

因为这里:

代码语言:javascript
复制
this.video.srcObject = stream

this.video为空。

这不是正确的方法。您应该准备一个dom元素的引用,将其指定为一个prop,然后从那里访问该元素。类似于:

代码语言:javascript
复制
class App extends Component {

  video = React.createRef()

  ...

  render() {

    navigator.mediaDevices.getUserMedia({ video: true })
      .then((stream) => {
        if ( this.video.current ) {
          this.video.current.srcObject = stream;
          this.video.current.play();
        }
      })

    return (

      ...

      <video ref={ this.video } 
             id="video" 
             width="640" 
             height="480" 
             autoplay
      />
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54498424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档