如何使用FFmpeg提取每第2个I帧并生成延时视频
使用FFmpeg直接提取每第2个I帧生成延时视频(无需临时文件)
完全可以不用生成全I帧临时视频,直接通过调整select滤镜表达式实现需求。
你的原命令用于提取所有I帧:
ffmpeg -i $FILE -vf "select='eq(pict_type,I)',setpts=N/FRAME_RATE/TB" -r 29.97 -vcodec libx264 -b:v 62M -an ./enc/${FILE}_cnv.mp4
要实现每2个I帧保留1个(比如原I帧序列1-8-16-24-32…保留1-16-32…),不需要依赖固定全局帧序号(比如你之前用的mod(n,16),仅适用于I帧间隔固定的场景),而是针对I帧自身计数判断,通用性更强:
正确的滤镜表达式与完整命令
ffmpeg -i $FILE -vf "select='eq(pict_type,I)*not(mod(nb_frames,2))',setpts=N/FRAME_RATE/TB" -r 29.97 -vcodec libx264 -b:v 62M -an ./enc/${FILE}_cnv.mp4
表达式细节解释
eq(pict_type,I):先筛选出所有I帧nb_frames:select滤镜内部仅对被筛选出的帧计数的变量(这里专门统计I帧的数量)not(mod(nb_frames,2)):当I帧计数为奇数(第1、3、5…个I帧)时保留,偶数时丢弃,刚好实现每2个I帧留1个的效果
为什么你的变通命令不够通用
你之前用的-vf "select='eq(pict_type,I)*not(mod(n,16))',setpts=N/FRAME_RATE/TB"是基于全局帧序号判断,只有当原视频I帧严格每8帧出现一次时才有效。如果视频中存在场景切换、编码参数变化导致I帧间隔改变,结果就会出错。而用nb_frames针对I帧计数,不管原视频I帧间隔是否均匀,都能稳定实现“每第2个I帧保留”的需求。
内容的提问来源于stack exchange,提问作者tol
相关产品推荐
相关产品推荐

