如何使用 react js 组件在网页上流式传输网络摄像头?

新手上路,请多包涵

我是 reactJS 的新手,正在尝试构建一个组件。

我想构建一个基本实用程序,其中我有一个显示实时网络摄像头提要的视频组件,并且会有一个捕获按钮,用于捕获提要的快照并将其存储到磁盘。我希望它在一个组件中(视频源 + 捕获按钮)

此代码在浏览器中流式传输提要,但我希望它在一个组件中,

 <body>
<div id="container">
    <video autoplay="true" id="videoElement">

    </video>
</div>
<script>
 var video = document.querySelector("#videoElement");

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

if (navigator.getUserMedia) {
    navigator.getUserMedia({video: true}, handleVideo, videoError);
}

function handleVideo(stream) {
    video.src = window.URL.createObjectURL(stream);
}

function videoError(e) {}
</script>
</body>
</html>

这工作正常,但不是它不是一个组件。

我尝试在 reaact js 中进行以下操作,但它不起作用:

 <body>
    <div id="container">

    </div>
    <script type="text/jsx">
        var MyComponent = React.createClass({
            handleVideo: function(stream) {
                video.src = window.URL.createObjectURL(stream);
            },
            videoError: function() {

            },
            render: function() {

            var video = document.querySelector("#videoElement");

            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

            if (navigator.getUserMedia) {
                navigator.getUserMedia({video: true}, this.handleVideo, this.videoError);
            }
                return <div>
                        <video autoplay="true" id="videoElement">
                        </video>
                       </div>;
            }
        });
    React.render( <MyComponent />, document.getElementById('container'));
    </script>
    </body>

错误在 handleVideo()

ReferenceError:未定义视频。

我对错误的理解是,

由于 video 标签出现在后面的部分(作为回报),它试图在 handleVideo 函数的定义之前使用。我很困惑如何使这项工作。

谢谢!

原文由 Arjun Chiddarwar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 516
2 个回答

关于 React 组件的工作方式,有几点需要了解。首先根据 React 文档

render() 函数应该是纯函数,这意味着它不会修改组件状态,每次调用都会返回相同的结果,并且不会直接与浏览器交互。

您应该将视频元素的初始化转移到备用生命周期方法,例如 componentDidMount 以确保它只被初始化一次。

其次,您很少需要直接与 DOM 交互。在这种情况下,我们可以使用组件的内部状态来管理视频流的 src 属性,确保它仅在流初始化后更新。

这是一个可能有效的更新组件:

 var MyComponent = React.createClass({
  getInitialState: function(){
    return { videoSrc: null }
  },
  componentDidMount: function(){
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
    if (navigator.getUserMedia) {
        navigator.getUserMedia({video: true}, this.handleVideo, this.videoError);
    }
  },
  handleVideo: function(stream) {
    // Update the state, triggering the component to re-render with the correct stream
    this.setState({ videoSrc: window.URL.createObjectURL(stream) });
  },
  videoError: function() {

  },
  render: function() {
    return <div>
      <video src={this.state.videoSrc} autoPlay="true" />
    </div>;
    }
});

原文由 Jordan Burnett 发布,翻译遵循 CC BY-SA 3.0 许可协议

答案中发布的一些代码已被弃用,可能不再适用于所有浏览器。

我创建了一个使用最新语法的新 React 应用程序。它非常简单明了。我希望它能帮助别人 :)

 class AppStreamCam extends React.Component {
  constructor(props) {
    super(props);
    this.streamCamVideo= this.streamCamVideo.bind(this)
  }
  streamCamVideo() {
    var constraints = { audio: true, video: { width: 1280, height: 720 } };
    navigator.mediaDevices
      .getUserMedia(constraints)
      .then(function(mediaStream) {
        var video = document.querySelector("video");

        video.srcObject = mediaStream;
        video.onloadedmetadata = function(e) {
          video.play();
        };
      })
      .catch(function(err) {
        console.log(err.name + ": " + err.message);
      }); // always check for errors at the end.
  }
  render() {
    return (
      <div>
        <div id="container">
          <video autoPlay={true} id="videoElement" controls></video>
        </div>
        <br/>
        <button onClick={this.streamCamVideo}>Start streaming</button>
      </div>
    );
  }
}

这是我关于它的 Medium 文章:

如何创建一个 React 应用程序来流式传输您的网络摄像头 |基础,初学者

如果有帮助别忘了鼓掌:)

最后,这是工作示例的 github 存储库: Basic-WebCam-Streamer

原文由 AG_HIHI 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题