简体   繁体   English

使用 React/NextJS useRef 切换网络摄像头视频失败

[英]Toggling webcam video with React/NextJS useRef failing

I've defined a Webcam component to use in a couple places in my codebase but it only renders on load.我已经定义了一个网络摄像头组件以在我的代码库中的几个地方使用,但它只在加载时呈现。 I'm trying to add a toggle to turn it on and off but am struggling to get it work.我正在尝试添加一个开关来打开和关闭它,但我正在努力让它工作。

Here's the TypeScript implementation of the component that I'm using in Next.js.这是我在 Next.js 中使用的组件的 TypeScript 实现。

import { useRef, useState, useEffect } from 'react'

export default function WebcamVideo() {
  const router = useRouter()
  const [mediaStream, setMediaStream] = useState<MediaStream>()
  const videoRef = useRef(null)

  useEffect(() => {
    setupWebcamVideo()
  }, [mediaStream])

  async function setupWebcamVideo() {
    if (!mediaStream) {
      await setupMediaStream()
    } else {
      const videoCurr = videoRef.current
      if (!videoCurr) return
      const video = videoCurr! as HTMLVideoElement
      if (!video.srcObject) {
        video.srcObject = mediaStream
      }
    }
  }

  async function setupMediaStream() {
    try {
      const ms = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: true })
      setMediaStream(ms)
    } catch (e) {
      alert('Camera is disabled')
      throw e
    }
  }
...
  return (
    <div className="w-full h-full relative z-0">
      <video className="h-full w-full mx-auto" ref={videoRef} autoPlay muted />
    </div>
  )
}

I'm using the component in this scenario:我在这种情况下使用该组件:

export default function SomePage() {
  const [toggleTab, setToggleTab] = useState(true)

  return (
    <div className="w-5/6 mx-auto">
      {toggleTab ? (
        <div className="h-44 w-full">
          <WebcamVideo />
        </d
      ) : (
        <div>
          <div className="font-bold mb-10 text-lg">Not webcam</div>
          <div className="h-96">
            <NonWebcam />
          </div>
        </div>
      )}
      <div onClick={() => setToggleTab(!toggleTab)}>Toggle webcam</div> 
    </div>
  )
}

After toggling twice, I don't see the Webcam video, but if I reload the page, it appears.切换两次后,我看不到网络摄像头视频,但如果我重新加载页面,它就会出现。

I've created CSB as commented above and video appears after toggling button twice.我已经按照上面的评论创建了 CSB,并且在切换按钮两次后会出现视频。

https://codesandbox.io/s/distracted-dew-9ge80?file=/src/App.js https://codesandbox.io/s/distracted-dew-9ge80?file=/src/App.js


import { useRef, useState, useEffect } from "react";

export default function WebcamVideo() {
  const [mediaStream, setMediaStream] = useState();
  const videoRef = useRef(null);

  useEffect(() => {
    // Moved to inside of useEffect because this function is depended on `mediaStream`
    async function setupWebcamVideo() {
      if (!mediaStream) {
        await setupMediaStream();
      } else {
        const videoCurr = videoRef.current;
        if (!videoCurr) return;
        const video = videoCurr;
        if (!video.srcObject) {
          video.srcObject = mediaStream;
        }
      }
    }
    setupWebcamVideo();
  }, [mediaStream]);

  async function setupMediaStream() {
    try {
      const ms = await navigator.mediaDevices.getUserMedia({
        video: { facingMode: "user" },
        audio: true
      });
      setMediaStream(ms);
    } catch (e) {
      alert("Camera is disabled");
      throw e;
    }
  }
  return (
    <div className="w-full h-full relative z-0">
      <video className="h-full w-full mx-auto" ref={videoRef} autoPlay muted />
    </div>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM