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

FFmpeg转码MKV为HTTP流几秒后停止问题求助

解决FFmpeg HTTP推流几秒后中断并报错-10054的问题

问题根源拆解

你碰到的Error number -10054是Windows系统下的WSAECONNRESET错误,说白了就是你的Node.js服务器主动切断了和FFmpeg的连接。看你贴的服务器代码就懂了——它只给FFmpeg返回了一个200响应头,之后完全没处理FFmpeg推送过来的数据流。TCP连接在长时间没有数据交互(或者说服务器不接收数据)的情况下,会被系统判定为超时无效,直接触发连接重置,这就是推流几秒就断的核心原因。

分步解决方案

1. 修复Node.js服务器的数据流处理逻辑

首先得让服务器能接收并处理FFmpeg发过来的流,下面给你两种常见场景的修正代码:

场景1:把推流保存为本地MP4文件

如果你的需求是把转码后的视频存到本地,用这段代码:

const http = require('http');
const fs = require('fs');
const port = 4012; // 替换成你实际用的端口
const ipAddress = '0.0.0.0'; // 允许所有IP访问,或者指定你的服务器IP

const server = http.createServer((req, res) => {
  // 给FFmpeg返回正确的响应头,告诉它我们准备好接收数据了
  res.writeHead(200, {
    'Content-Type': 'video/mp4',
    'Connection': 'keep-alive'
  });

  // 创建本地文件写入流
  const outputStream = fs.createWriteStream('transcoded_output.mp4');
  // 把FFmpeg推送的数据流直接管道到本地文件
  req.pipe(outputStream);

  // 监听写入完成事件
  outputStream.on('finish', () => {
    console.log('转码后的视频已保存');
    res.end();
  });

  // 处理可能的错误
  req.on('error', (err) => {
    console.error('接收数据流出错:', err);
    outputStream.destroy();
    res.end();
  });
});

server.listen(port, ipAddress, () => {
  console.log(`服务器已启动,监听 http://${ipAddress}:${port}`);
});
场景2:把推流实时转发给客户端(比如浏览器)

如果需要让其他设备实时观看这个流,你可以让服务器把FFmpeg的数据流转发给请求的客户端。注意:实时HTTP流推荐用HLS或DASH,但简单场景下可以先这么处理:

const http = require('http');
const port = 4012;
const ipAddress = '0.0.0.0';

// 用一个全局变量保存FFmpeg的数据流,用于转发给客户端
let streamSource = null;

const server = http.createServer((req, res) => {
  // 如果是FFmpeg的推流请求(POST方法,携带视频数据)
  if (req.method === 'POST') {
    res.writeHead(200, {
      'Content-Type': 'video/mp4',
      'Connection': 'keep-alive'
    });
    // 保存推流的数据源
    streamSource = req;
    // 消费数据流,避免连接被重置
    req.on('data', () => {});
    req.on('end', () => {
      streamSource = null;
      res.end();
    });
  } else {
    // 客户端拉流请求
    if (!streamSource) {
      res.writeHead(404, {'Content-Type': 'text/plain'});
      res.end('没有可用的视频流');
      return;
    }
    res.writeHead(200, {
      'Content-Type': 'video/mp4',
      'Transfer-Encoding': 'chunked'
    });
    // 把FFmpeg的数据流转发给客户端
    streamSource.pipe(res);
  }
});

server.listen(port, ipAddress, () => {
  console.log(`服务器已启动,推流地址:http://${ipAddress}:${port},拉流地址同上`);
});

2. 优化FFmpeg推流命令

你的原命令推的是MPEG1视频流,但目标是MP4容器,建议调整参数让转码和推流更适配HTTP场景:

ffmpeg -i "input.mkv" -c:v libx264 -c:a aac -vf "scale=640:480" -r 20 -f mp4 -movflags frag_keyframe+empty_moov http://localhost:4012

参数解释:

  • -c:v libx264:用H.264编码,比MPEG1更高效,是MP4容器的标准编码
  • -c:a aac:MP4标准的音频编码,兼容性更好
  • -movflags frag_keyframe+empty_moov:生成碎片化MP4,适合HTTP流式传输,不需要等整个视频的索引头生成,推流可以立即开始

3. 排查其他可能的问题

如果修改后还是有问题,可以检查这几点:

  • 防火墙是否放行指定的端口(比如4012)
  • FFmpeg命令里的服务器IP是否正确(确保能访问到你的Node服务器)
  • 查看FFmpeg的完整日志,是否有编码相关的警告(比如输入文件的编码问题)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:43:57