簡體   English   中英

使用 React/NextJS useRef 切換網絡攝像頭視頻失敗

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

我已經定義了一個網絡攝像頭組件以在我的代碼庫中的幾個地方使用,但它只在加載時呈現。 我正在嘗試添加一個開關來打開和關閉它,但我正在努力讓它工作。

這是我在 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>
  )
}

我在這種情況下使用該組件:

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>
  )
}

切換兩次后,我看不到網絡攝像頭視頻,但如果我重新加載頁面,它就會出現。

我已經按照上面的評論創建了 CSB,並且在切換按鈕兩次后會出現視頻。

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