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

TensorFlow.js配合React Web应用使用coco-ssd检测视频仅返回单次预测如何解决

问题核心原因

你当前的代码仅在依赖状态变更时触发一次预测,没有持续的帧检测循环,同时captureStream参数配置错误导致仅能捕获首帧,因此无法实现逐帧检测。


具体修改方案

  1. 新增帧循环控制和并发锁的ref,避免重复执行和内存泄漏
// 头部引入useCallback
import React, { useEffect, useRef, useState, useCallback } from "react";

// 组件内新增以下ref
const rafIdRef = useRef(null);
const predictingRef = useRef(false);
  1. 修正captureStream的参数,原来的0代表仅捕获静态首帧,改为需要的捕获帧率即可持续获取视频帧
// 找到原来的captureStream调用,修改为
_videoStream.srcObject = _video.captureStream(30);
  1. 新增预测循环逻辑,用requestAnimationFrame实现播放过程中持续检测
// 组件内新增回调函数包裹预测逻辑
const runPredictionLoop = useCallback(async () => {
  // 未满足运行条件时继续循环等待
  if (!videoPlaying || !streamReady || !models?.coco_ssd || !videoStreamRef.current || !canvasRef.current) {
    rafIdRef.current = requestAnimationFrame(runPredictionLoop);
    return;
  }
  // 避免上一次预测未完成时重复调用导致性能问题
  if (predictingRef.current) {
    rafIdRef.current = requestAnimationFrame(runPredictionLoop);
    return;
  }
  try {
    predictingRef.current = true;
    const predictions = await models.coco_ssd.detect(videoStreamRef.current);
    console.log(predictions);
    // 此处添加canvas绘制边界框的逻辑即可
  } catch (err) {
    console.error("预测失败", err);
  } finally {
    predictingRef.current = false;
    rafIdRef.current = requestAnimationFrame(runPredictionLoop);
  }
}, [videoPlaying, streamReady, models]);
  1. 新增useEffect控制循环的启动和销毁
// 组件内新增useEffect
useEffect(() => {
  if (videoPlaying && streamReady) {
    runPredictionLoop();
  }
  // 组件卸载/状态变更时清除循环,避免内存泄漏
  return () => {
    if (rafIdRef.current) {
      cancelAnimationFrame(rafIdRef.current);
    }
  };
}, [videoPlaying, streamReady, runPredictionLoop]);
  1. 可选优化:可以直接使用第一个video元素作为detect方法的输入,不需要额外的第二个video中转流,减少资源占用。

内容的提问来源于stack exchange,提问作者hyprstack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:27:03