使用react-use-face-detection时组件卸载后react-webcam未关闭的解决方法
修复React人脸识别组件卸载时Webcam无法关闭的问题
问题原因
react-use-face-detection 默认不会自动在组件卸载时停止 MediaPipe 的 Camera 实例,也不会主动释放摄像头的媒体流资源,导致组件卸载后摄像头仍被占用,无法正常关闭。
解决方案
通过手动跟踪 Camera 实例,并在组件卸载时执行停止和资源释放操作来解决:
步骤1:创建 ref 存储 Camera 实例
使用 useRef 创建一个引用,用来保存配置中创建的 Camera 实例,方便后续访问控制。
步骤2:修改 camera 配置,存入实例到 ref
在 useFaceDetection 的 camera 工厂函数中,将创建好的 Camera 实例存入之前创建的 ref。
步骤3:利用 useEffect 清理函数停止 Camera 并释放流
添加 useEffect 钩子,在组件卸载时调用 Camera.stop() 终止帧处理,同时释放摄像头的媒体流轨道。
修改后的完整代码
import { useRef, useEffect } from 'react'; import { useFaceDetection } from 'react-use-face-detection'; import { FaceDetection } from '@mediapipe/face_detection'; import { Camera } from '@mediapipe/camera_utils'; function FaceDetectionComponent() { const cameraRef = useRef(null); const { webcamRef, boundingBox, isLoading, detected, facesDetected } = useFaceDetection({ faceDetectionOptions: { model: 'short' }, faceDetection: new FaceDetection.FaceDetection({ locateFile: (file) => `/face_detection/${file}` }), camera: ({ mediaSrc, onFrame, width, height }) => { const camera = new Camera(mediaSrc, { onFrame, width, height }); cameraRef.current = camera; return camera; } }); // 组件卸载时清理资源 useEffect(() => { return () => { if (cameraRef.current) { cameraRef.current.stop(); // 释放摄像头媒体流 const stream = webcamRef.current?.srcObject; stream?.getTracks().forEach(track => track.stop()); } }; }, [webcamRef]); return ( <div> {isLoading && <p>加载中...</p>} <video ref={webcamRef} autoPlay playsInline /> {/* 此处添加人脸框绘制等业务逻辑 */} </div> ); } export default FaceDetectionComponent;
关键细节说明
cameraRef:解决了useFaceDetection配置中创建的Camera实例无法外部访问的问题,确保我们能在组件卸载时控制它。Camera.stop():终止 MediaPipe 对摄像头帧的捕获和处理,停止人脸识别流程。- 媒体流释放:通过遍历
srcObject的所有轨道并调用stop(),彻底释放摄像头的硬件资源,避免浏览器持续占用设备。
内容的提问来源于stack exchange,提问作者Prageeth Milan
相关产品推荐
相关产品推荐

