网络摄像头在离开 React 组件时不会关闭



我目前正在 React 应用程序中从网络摄像头拍照。但是,当我离开组件时,绿灯继续亮起,我似乎无法关闭网络摄像头。这是我用来使用网络摄像头的代码。

  navigator.webkitGetUserMedia({ video: true, audio: false }, function(stream) {
    video.srcObject = stream;
    window.localstream = stream;
    video.play();
  }, function (e) {
    console.log(e);
  })

稍后,在我的组件 WillUnmount 生命周期处理程序中,我运行以下代码:

video.pause();
video.srcObject = null;
window.localstream.getTracks()[0].stop();
var list = document.getElementById("video"); 
list.removeChild(list.childNodes[0])

我的网络摄像头没有关闭,但是当我控制台时.log MediaStreamTrack的readyState ="结束"并且启用等于false。有什么方法可以强制关闭网络摄像头吗?

React为你提供了像useEffect,useRef等惊人的钩子。您需要做的就是在离开页面或关闭组件时停止视频轨道。

useEffect(() => {
  /*
   * action on opening page:
   * as example you could get all video devices and
   * to choose which camera exactly you want to use
   */
  getDevices()
  return () => {
    stopVideo();
  };
}, []);

由于我们在useEffect钩子中有return语句,因此每次我们离开页面时都会调用函数stopVideo()。

现在假设您将当前视频轨道存储在状态中

const [videoStream, setVideoStream] = useState<MediaStream>();

然后停止视频流的功能将如下所示:

function stopVideo() {
   if (videoStream) {
     videoStream.getTracks().forEach((track: any) => {
       if (track.readyState === "live") {
         track.stop();
       }
     });
   }
 }

在代码沙盒中查看

简介:要转动相机,您必须停止轨道,因此,如果您要添加如下所示的项目useEffect,它将帮助您实现目标。

  useEffect(() => {
    let videoElement: HTMLVideoElement | undefined
    if (videoRef.current) {
      videoElement = videoRef.current
    }
    return () => {
      if (videoElement && videoElement.srcObject) {
        (videoElement.srcObject as MediaStream).getTracks().forEach((track: any) => {
          if (track.readyState == 'live') {
            track.stop()
          }
        })
      }
    }
  }, [videoRef])