使用fluent-ffmpeg流式输出视频时长异常(截断)问题求助
视频流式传输截断问题排查与解决
我用fluent-ffmpeg实现无文件保存的视频流式传输,原视频20秒,但输出仅12秒,试了多种输出选项都没解决,需要让网页播放器能获取正确的流时长。
现有代码
let imageData = []; let tmp = {}; tmp.filter = 'overlay'; tmp.inputs = '[0:v][1:v]'; tmp.options = {}; //tmp.options.enable = `between(t,${image.startAt}, ${image.endAt})`; tmp.options.x = imagePositionX; tmp.options.y = imagePositionY; tmp.outputs = 'tmp'; imageData.push(tmp); let size = await ufs(videoURL); res.status(206); res.set('Content-Type', 'video/mp4'); if (req.headers.range) { let range = req.headers.range; let parts = range.replace(/bytes=/, "").split("-"); let partialstart = parts[0]; let partialend = parts[1]; let start = parseInt(partialstart, 10); let end = partialend ? parseInt(partialend, 10) : size-1; let chunksize = (end-start)+1; res.set('Content-Range', 'bytes ' + start + '-' + end + '/' + size); res.set('Accept-Ranges', 'bytes'); res.set('Content-Length', chunksize); } else { res.set('Content-Length', size); } let stream = ffmpeg(videoURL) .input(imageURL) .videoCodec('libx264') .audioCodec('aac') .fps('29.97') .complexFilter(imageData, 'tmp') .outputOptions([ '-movflags frag_keyframe+empty_moov', '-frag_duration 100', '-pix_fmt yuv420p', '-map 0:a?', '-b:v 2400k', '-b:a 160k', '-minrate 200k', '-maxrate 1300k', '-bufsize 13000k', '-f mp4', ]) .on('end', () => { console.log('file has been converted succesfully'); }) .on('error', (err) => { console.log('error : ', err.message) }) .pipe(res, {end: true})
问题解决思路
1. 修复Range请求处理逻辑
你当前用原视频的文件大小处理Range请求,但流式输出的是ffmpeg处理后的新视频,原视频字节数和处理后的流完全不匹配,会导致播放器误以为流已结束。流式场景下无法提前获取处理后的文件大小,因此要移除基于原视频的Range处理:
// 替换原有的响应头设置逻辑 res.status(200); res.set('Content-Type', 'video/mp4'); // 无需设置Content-Length,让流式输出自动处理
2. 优化ffmpeg输出参数
调整movflags和分片配置,避免播放器解析异常导致的截断:
.outputOptions([ '-movflags frag_keyframe+empty_moov+default_base_moof', // 提升流式兼容性 '-pix_fmt yuv420p', '-map 0:a?', '-b:v 2400k', '-b:a 160k', '-minrate 200k', '-maxrate 1300k', '-bufsize 13000k', '-avoid_negative_ts make_zero', // 修复时间戳异常问题 '-f mp4', ])
- 移除
-frag_duration 100:过小的分片间隔会导致播放器解析负担过重,容易触发提前终止 - 添加
default_base_moof:让每个分片成为独立单元,提升网页播放器的兼容性 - 添加
avoid_negative_ts make_zero:避免时间戳异常导致的播放器时长计算错误
3. 排查ffmpeg进程异常
添加stderr监听,查看ffmpeg是否因错误提前终止:
.on('stderr', function(stderrLine) { console.log('FFmpeg stderr: ' + stderrLine); })
4. 确保滤镜不截断主视频
后续启用enable参数控制overlay显示时段时,要保证主视频流完整输出,仅控制overlay的显示周期,避免滤镜逻辑误截断视频。
内容的提问来源于stack exchange,提问作者Floz42
相关产品推荐
相关产品推荐

