src/hooks/useCamera.ts 1.4 K raw
1
import { useEffect, useRef, useState } from "react";
2
3
export function useCamera() {
4
  const videoRef = useRef<HTMLVideoElement>(null);
5
  const [error, setError] = useState<string | null>(null);
6
  const [isReady, setIsReady] = useState(false);
7
8
  useEffect(() => {
9
    let stream: MediaStream | null = null;
10
11
    async function init() {
12
      try {
13
        stream = await navigator.mediaDevices.getUserMedia({
14
          video: { facingMode: "user", width: { ideal: 1280 }, height: { ideal: 720 } },
15
          audio: false,
16
        });
17
        if (videoRef.current) {
18
          videoRef.current.srcObject = stream;
19
          videoRef.current.onloadedmetadata = () => {
20
            videoRef.current!.play();
21
            setIsReady(true);
22
          };
23
        }
24
      } catch (err) {
25
        if (err instanceof DOMException) {
26
          if (err.name === "NotAllowedError") {
27
            setError("Camera access denied. Please allow camera permissions.");
28
          } else if (err.name === "NotFoundError") {
29
            setError("No camera found. Please connect a camera.");
30
          } else {
31
            setError(`Camera error: ${err.message}`);
32
          }
33
        } else {
34
          setError("Failed to access camera.");
35
        }
36
      }
37
    }
38
39
    init();
40
41
    return () => {
42
      if (stream) {
43
        stream.getTracks().forEach((t) => t.stop());
44
      }
45
    };
46
  }, []);
47
48
  return { videoRef, error, isReady };
49
}