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

如何在React中渲染Node.js返回的多个输出以展示视频转码进度

问题根因

你的现有代码逻辑存在明显的时序错误:res.end() 是同步执行的,而 hbjs.spawn 的 progress 事件是异步触发的,不等进度事件回调执行,HTTP响应就已经被关闭,自然拿不到任何返回值,这个问题和是否改用EJS没有任何关联。

可行实现方案

方案1:SSE(服务器推送事件,推荐)

适合单向下发进度的场景,轻量无需额外依赖,前端原生支持。

后端改造代码

app.get('/transcode-progress', (req, res) => {
  // 设置SSE响应头
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  const transcodeTask = hbjs.spawn({
    input: '你的输入文件路径',
    output: '你的输出文件路径'
  })
  .on('progress', progress => {
    // SSE消息格式要求前缀 data: ,后缀\n\n
    res.write(`data: ${progress.percentComplete}\n\n`);
  })
  .on('end', () => {
    // 转码完成后关闭响应
    res.write(`data: 100\n\n`);
    res.end();
  })
  .on('error', err => {
    // 错误处理
    res.write(`data: error:${err.message}\n\n`);
    res.end();
  });

  // 客户端断开连接时清理转码任务,避免资源泄漏
  req.on('close', () => {
    transcodeTask.kill();
  });
});

前端React代码

import { useState, useEffect } from 'react';

function TranscodePage() {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const eventSource = new EventSource('/transcode-progress');
    eventSource.onmessage = (event) => {
      const data = event.data;
      if (data.startsWith('error:')) {
        console.error('转码出错:', data.slice(6));
        eventSource.close();
        return;
      }
      const currentProgress = Number(data);
      setProgress(currentProgress);
      if (currentProgress >= 100) {
        eventSource.close();
        // 转码完成后续逻辑
      }
    };
    eventSource.onerror = () => {
      eventSource.close();
    };
    return () => {
      eventSource.close();
    };
  }, []);

  return <div>转码进度:{progress}%</div>;
}

方案2:WebSocket(适合需要双向交互的场景)

如果你的应用后续还有其他实时交互需求,可以用Socket.io实现:

  • 后端监听客户端的转码请求,启动转码任务后,每次触发progress事件就向对应客户端发送进度消息
  • 前端WebSocket连接成功后发起转码请求,监听进度消息更新状态即可

方案3:轮询(实现最简单,适合小型项目)

  • 后端新增两个接口:一个是启动转码接口,返回唯一的任务ID,同时将任务进度存在内存/Redis中
  • 另一个是进度查询接口,接收任务ID返回当前进度
  • 前端拿到任务ID后,每隔300-500ms调用一次查询接口拉取进度,进度到100或报错后停止轮询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:39:03