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
相关产品推荐
相关产品推荐

