如何在单个FFmpeg进程中检测黑帧并在检测到的黑帧位置添加关键帧
如何在单个FFmpeg进程中检测黑帧并在检测到的黑帧位置添加关键帧
嘿,这个需求完全可以在单个FFmpeg进程里实现!你现在的命令已经能用blackdetect滤镜检测黑帧了,我们只需要给它加上强制关键帧的逻辑,让FFmpeg在检测到黑帧的位置自动生成关键帧就行。
核心思路是利用blackdetect滤镜给黑帧添加的元数据,配合-force_key_frames选项来触发关键帧生成。blackdetect会给检测到的黑帧添加lavfi.blackdetect.black_start这类元数据,我们可以通过表达式让FFmpeg在存在该元数据的帧位置强制生成关键帧。
给你整理好的完整命令:
ffmpeg -i in.mp4 -vf "blackdetect=d=0.5:pic_th=0.98" -force_key_frames "expr:metadata_exists('lavfi.blackdetect.black_start')" -c:v libx264 -preset slow -crf 18 output.mp4
我给你拆解下关键参数的作用:
blackdetect=d=0.5:pic_th=0.98:和你原来的设置一致,d=0.5表示只有持续至少0.5秒的黑帧才会被识别,pic_th=0.98是亮度阈值(数值越小要求画面越暗),你可以根据自己的视频情况调整这两个值。-force_key_frames "expr:metadata_exists('lavfi.blackdetect.black_start')":这个是核心新增的参数,它告诉FFmpeg:只要当前帧的元数据里存在lavfi.blackdetect.black_start(也就是这一帧是黑帧的起始帧),就强制生成关键帧,完美对应你要的需求。- 后面的
-c:v libx264 -preset slow -crf 18是你原来的编码配置,用来保证输出视频的质量和编码效率。
如果你需要在黑帧的整个持续区间内都强制生成关键帧(而不只是起始帧),可以把-force_key_frames的表达式改成这样:
-force_key_frames "expr:metadata_exists('lavfi.blackdetect.black_start') || metadata_exists('lavfi.blackdetect.black_end') || between(t, metadata('lavfi.blackdetect.black_start'), metadata('lavfi.blackdetect.black_end'))"
不过一般来说,黑帧起始位置的关键帧就足够满足大多数场景的需求啦。
备注:内容来源于stack exchange,提问作者Raymond




