"use client"; import { useEffect, useRef, useState } from "react"; import Webcam from "react-webcam"; import * as faceapi from "face-api.js"; import { Button } from "@/components/ui/button"; import { Camera } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; const MODEL_URL = "https://cdn.jsdelivr.net/npm/@vladmandic/face-api/model"; const RealtimeFaceDetection = () => { const webcamRef = useRef(null); const canvasRef = useRef(null); const [isModelLoaded, setIsModelLoaded] = useState(false); const [isDetecting, setIsDetecting] = useState(false); const { toast } = useToast(); useEffect(() => { const loadModels = async () => { try { await faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL); await faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL); await faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL); setIsModelLoaded(true); } catch (error) { console.error("Error loading models:", error); toast({ title: "Error", description: "Failed to load face detection models.", variant: "destructive", }); } }; loadModels(); }, [toast]); const detectFace = async () => { if (!webcamRef.current || !webcamRef.current.video) return; const video = webcamRef.current.video; const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); if (!context) return; canvas.width = video.videoWidth; canvas.height = video.videoHeight; context.drawImage(video, 0, 0, canvas.width, canvas.height); // Convert the canvas to a Blob (image file) canvas.toBlob(async (blob) => { if (!blob) return; // Detect face const detections = await faceapi .detectSingleFace(video, new faceapi.TinyFaceDetectorOptions()) .withFaceLandmarks() .withFaceDescriptor(); if (detections) { sendFaceDataToAPI(blob); } }, "image/jpeg"); // Save image as JPEG }; const sendFaceDataToAPI = async (imageBlob: Blob) => { try { const formData = new FormData(); formData.append("image", imageBlob, "face.jpg"); const response = await fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/search`, { method: "POST", body: formData, // Send multipart/form-data } ); const data = await response.json(); toast({ title: data?.name, description: data.message }); } catch (error) { console.error("Error sending face data:", error); toast({ title: "Error", description: "Failed to send face data.", variant: "destructive", }); } }; const startDetection = () => { if (!isModelLoaded) return; setIsDetecting(true); const interval = setInterval(detectFace, 1000); setTimeout(() => { clearInterval(interval); setIsDetecting(false); }, 100000); // Stops detection after 10 seconds }; return (
); }; export default RealtimeFaceDetection;