You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:25:26