如何结合使用react-video-recorder与TensorFlow插件?联用失败但react-webcam可用
解决react-video-recorder与TensorFlow COCO-SSD结合的问题
问题原因
你之前用react-webcam时,组件ref直接暴露了包含video元素的实例,能通过webcamRef.current.video获取视频流;但react-video-recorder的ref结构不同,直接绑定ref到组件无法拿到内部video元素,导致TensorFlow模型找不到检测源。
解决方案
核心是通过react-video-recorder提供的videoRef属性传入自定义ref,正确获取内部video元素,同时优化检测循环性能并清理定时器避免内存泄漏。
修改后的完整代码
import { useRef, useEffect } from 'react'; import VideoRecorder from 'react-video-recorder'; import * as cocossd from '@tensorflow-models/coco-ssd'; function VideoRecord() { const videoRecorderRef = useRef(null); const videoRef = useRef(null); const canvasRef = useRef(null); const runCoco = async () => { const net = await cocossd.load(); console.log("COCO-SSD模型加载完成。"); // 约30fps检测频率,平衡精度与性能 const intervalId = setInterval(() => { detect(net); }, 33); return () => clearInterval(intervalId); }; const detect = async (net) => { if (!videoRef.current || videoRef.current.readyState !== 4) { return; } const video = videoRef.current; const videoWidth = video.videoWidth; const videoHeight = video.videoHeight; video.width = videoWidth; video.height = videoHeight; canvasRef.current.width = videoWidth; canvasRef.current.height = videoHeight; const detections = await net.detect(video); const ctx = canvasRef.current.getContext("2d"); drawRect(detections, ctx); }; useEffect(() => { const cleanup = runCoco(); return cleanup; }, []); return ( <div className="App"> <header className="App-header"> <VideoRecorder ref={videoRecorderRef} videoRef={videoRef} className="videoRecord" timeLimit={20000} onRecordingComplete={videoBlob => { console.log('videoBlob', videoBlob); }} /> <canvas ref={canvasRef} style={{ position: "absolute", marginLeft: "auto", marginRight: "auto", left: 0, right: 0, textAlign: "center", zIndex: 8, width: 640, height: 480, }} /> </header> </div> ); } // 补充drawRect函数基础实现 function drawRect(detections, ctx) { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); detections.forEach(det => { ctx.strokeStyle = "#00ff00"; ctx.lineWidth = 2; ctx.strokeRect(det.bbox[0], det.bbox[1], det.bbox[2], det.bbox[3]); ctx.fillStyle = "#00ff00"; ctx.font = "16px Arial"; ctx.fillText(`${det.class} (${Math.round(det.score * 100)}%)`, det.bbox[0], det.bbox[1] > 10 ? det.bbox[1] - 5 : 10); }); } export default VideoRecord;
关键修改点
- 新增
videoRef专门指向组件内部video元素,通过videoRef属性传入react-video-recorder - 调整检测定时器间隔为33ms,避免过高频率占用性能
- 在
useEffect中添加定时器清理逻辑,防止组件卸载后内存泄漏 - 补充
drawRect函数的基础绘制逻辑(原代码未提供)
内容的提问来源于stack exchange,提问作者Elchin
相关产品推荐
相关产品推荐

