ffmpeg使用-c copy裁剪视频音画不匹配问题解决方案
ffmpeg裁剪视频音画同步+提速方案
流复制模式下视频延迟的核心原因是:流复制不会重新编码视频,只能从离指定时间点最近的关键帧开始截取视频流,如果指定的起始时间点不是关键帧,视频流的实际起始位置就会和音频流错位,进而出现音频先播、视频晚出的问题。
方案1:保留-c copy流复制(最快,无编码损失)
流复制模式下不需要重新编码,处理速度是所有方案里最快的,也不会损失画质,通过参数调整可以解决绝大多数时间戳错位导致的音画不同步问题:
- 把
-ss参数移到-i输入参数之前,启用输入级快速定位,比放在-i后面的输出级定位速度更快,定位偏差更小 - 追加
-avoid_negative_ts make_zero参数,强制把输出文件的起始时间戳重置为0,消除时间戳偏移 - 最终可直接使用的命令:
ffmpeg -ss 00:05:20 -i input.mp4 -t 00:10:00 -c:v copy -c:a copy -avoid_negative_ts make_zero output.mp4
注意:流复制的裁剪精度上限由原视频的关键帧间隔决定,一般普通视频的关键帧间隔在2-10秒,如果要求裁剪时间精确到毫秒级、完全没有偏差,流复制模式无法满足需求,必须使用重新编码模式。
方案2:重新编码模式(精度最高,可调参数提速)
重新编码模式可以精确到任意时间点裁剪,完全保证音画同步,通过以下参数调整可以把处理速度提升数倍:
- 优先使用硬件编码:现在绝大多数服务器的CPU(Intel核显)、独立显卡(N卡/A卡)都支持h264硬件编码,速度比纯软件编码快5-10倍,画质损失肉眼几乎不可察
- Intel核显用
h264_qsv编码器,命令示例:
ffmpeg -ss 00:05:20 -i input.mp4 -t 00:10:00 -c:v h264_qsv -c:a copy output.mp4- N卡用
h264_nvenc编码器,A卡用h264_amf编码器,替换上面命令里的编码器名称即可
- Intel核显用
- 没有硬件加速条件时,调整软件编码的preset参数:默认libx264编码器用的是
medium预设,把预设改成veryfast可以把编码速度提升2-3倍,只要码率设置合理,普通场景完全看不出画质差别,命令示例:
ffmpeg -ss 00:05:20 -i input.mp4 -t 00:10:00 -c:v libx264 -preset veryfast -crf 23 -c:a copy output.mp4
- 通用提速技巧:不管用哪种编码方式,都把
-ss放在-i前面,ffmpeg会直接跳过指定时间点之前的内容,不需要解码这部分片段,能再减少30%左右的处理耗时;音频流可以一直用-c:a copy直接复制,音频编码本身耗时不高但没必要重复编码,能省一点时间是一点。
PHP调用注意事项
- 调用时写全ffmpeg的可执行文件绝对路径,不要用相对路径,避免环境变量不生效、权限不足的问题
- 所有传入命令的文件路径、时间参数都要做转义,不要直接拼接用户传入的参数,避免命令注入漏洞
- 处理大体积视频时可以把进程放到后台运行,避免PHP请求超时中断处理
内容的提问来源于stack exchange,提问作者Barry
相关产品推荐
相关产品推荐

