使用FFmpeg单命令滤镜实现指定时间点帧冻结的技术咨询
FFmpeg单命令滤镜实现指定时间点帧冻结的技术咨询
嘿,这需求太常见了,完全不用拆成多条命令折腾!我给你准备了两种单命令的滤镜方案,都是FFmpeg原生支持的,操作起来很简单:
方案一:拆分+循环+拼接(直观易理解)
这个思路是把视频分成两段:前19分59秒正常播放,从20:00开始用19:59的帧循环填充,最后把两段拼接起来。具体命令如下:
ffmpeg -i input.mp4 -filter_complex " [0:v]trim=end=1199,setpts=PTS-STARTPTS[v1]; [0:v]trim=start=1199:end=1200,loop=999999:size=1,setpts=PTS-STARTPTS[v2]; [v1][v2]concat=n=2:v=1:a=0[v]" -map "[v]" -map 0:a -c:a copy output.mp4
各参数解释:
trim=end=1199:截取原视频前1199秒(也就是00:19:59)的内容,setpts=PTS-STARTPTS用来重置时间戳,避免拼接后播放卡顿trim=start=1199:end=1200:精准截取00:19:59到00:20:00这一帧,loop=999999:size=1表示把这1帧循环999999次(次数足够大,能覆盖视频剩余时长)concat=n=2:v=1:a=0:把前两段视频拼接成一个完整视频,只处理视频流不处理音频-map 0:a -c:a copy:直接复制原视频的音频流,不用重新编码,节省时间
方案二:叠加冻结帧(更灵活)
这个方法是保留原视频完整流,到指定时间点后用冻结帧覆盖原画面,适合需要保留原视频其他滤镜处理逻辑的场景:
ffmpeg -i input.mp4 -filter_complex " [0:v]split[v0][v1]; [v1]trim=start=1199:end=1200,loop=999999:size=1,setpts=PTS-STARTPTS[freeze]; [v0][freeze]overlay=x=0:y=0:enable='gte(t,1200)'[v]" -map "[v]" -map 0:a -c:a copy output.mp4
各参数解释:
split[v0][v1]:把原视频流拆成两路,v0保留完整原视频,v1用来生成冻结帧enable='gte(t,1200)':设置只有当播放时间t大于等于1200秒(00:20:00)时,才把冻结帧叠加到原视频上,前面的画面正常播放
小提示
- 如果你的视频没有音频,可以去掉命令里的
-map 0:a -c:a copy部分 - 要是想精确计算
loop的次数,可以用原视频总时长减去1200秒,比如原视频总长1500秒,那loop=300:size=1就足够,不过写999999这种大数字也完全没问题,FFmpeg会自动在视频结束时停止循环
备注:内容来源于stack exchange,提问作者Vadim Kantorov
相关产品推荐
相关产品推荐

