使用Node.js fluent-ffmpeg拼接MP4视频时出现画面冻结问题求助
问题诊断与解决
你的问题核心在于输入视频参数不统一,再加上ffmpeg参数的矛盾配置,导致拼接时流不兼容,出现画面冻结、片段丢失的情况。具体问题点和修复方案如下:
1. 先解决参数冲突
你的输出选项里同时写了-c copy和-c:v libx264,这两个是互斥的:
-c copy是直接复制音视频流,不重新编码,速度快但要求所有输入流参数完全一致;-c:v libx264是强制重新编码视频,这时候-c copy会被忽略,但你没统一音频编码,也没处理分辨率差异。
直接删掉-c copy,确保全程重新编码,适配不同输入的参数差异。
2. 统一输入视频的核心参数
你用的四个视频分辨率不一样(2160p/1080p)、帧率可能也不同,concat demuxer对输入流的一致性要求极高,参数不匹配就会出现画面异常。修复时要强制统一以下参数:
- 分辨率:选一个目标分辨率(比如统一到1080p,用
-vf scale=1920:1080); - 帧率:和你指定的
-r 30保持一致; - 音频编码:加上
-c:a aac统一音频编码,避免音频流不兼容; - 像素格式:加上
-pix_fmt yuv420p,保证播放器兼容性。
3. 修正concat文件的路径格式
Windows下ffmpeg解析路径时,反斜杠\需要转成双反斜杠\\或者正斜杠/,否则可能导致路径解析错误,部分视频无法正确读取。修改后的concat.txt应该是:
file 'src/input/d69de4a3-2b72-462c-be70-f8b8287b45e0/pexels-fred-c-19065853 (Original).mp4' file 'src/input/d69de4a3-2b72-462c-be70-f8b8287b45e0/pexels-imad-clicks-16270463 (2160p).mp4' file 'src/input/d69de4a3-2b72-462c-be70-f8b8287b45e0/pexels-peter-fowler-9683061 (2160p).mp4' file 'src/input/d69de4a3-2b72-462c-be70-f8b8287b45e0/pexels-sascha-5799767 (1080p).mp4'
注意给带空格的文件名加上单引号,避免解析错误。
4. 修改后的完整fluent-ffmpeg代码
const ffmpeg = require('fluent-ffmpeg'); ffmpeg() .input(concatFilePath) .inputOptions(['-f concat', '-safe 0']) // 统一视频参数:缩放至1080p,强制30帧,指定像素格式 .outputOptions([ '-c:v libx264', '-b:v 5M', '-r 30', '-preset slow', '-vf scale=1920:1080', '-pix_fmt yuv420p', '-c:a aac', // 统一音频编码 '-b:a 192k' ]) .on('end', () => { console.log('Video clips concatenated successfully.'); }) .on('error', (err) => { console.error('Error concatenating video clips:', err); console.log('Cleaning up...'); deleteOutputFolder(outputDir); }) .save(outputPath);
额外排查建议
如果还是有问题,先单独用ffmpeg命令行测试拼接,排除fluent-ffmpeg的封装问题:
ffmpeg -f concat -safe 0 -i concat.txt -c:v libx264 -b:v 5M -r 30 -preset slow -vf scale=1920:1080 -pix_fmt yuv420p -c:a aac -b:a 192k output.mp4
如果命令行正常,再检查fluent-ffmpeg的配置是否正确;如果命令行也出问题,用ffprobe查看每个输入视频的参数,确认是否有其他不一致的地方(比如音频采样率):
ffprobe -v quiet -print_format json -show_format -show_streams your-video-file.mp4
内容的提问来源于stack exchange,提问作者Rasmus Puls
相关产品推荐
相关产品推荐

