结合场景过滤器(用于检测场景变化)和showinfo过滤器应该可以达到你想要的效果:
ffmpeg -i input.flv \
-filter:v "select='gt(scene,0.4)',showinfo" \
-f null \
- 2> ffout
此命令提取与前一帧相差超过 ( gt
)的所有帧0.4
(范围从0
到1
)。对于这些帧,信息会showinfo
像这样打印出来 ( )
[Parsed_showinfo_1 @ 0x2d85e60] n: 0 pts:2537204 pts_time:2.5372 pos: 2998114 fmt:rgb24 sar:1/1 s:1920x1200 i:P iskey:1 type:I checksum:5616582E plane_checksum:[5616582E]
现在您只需要提取时间戳。我想你对pts_time
. 你可以这样做:
grep showinfo ffout | grep pts_time:[0-9.]* -o | grep [0-9.]* -o > timestamps
这将为您提供所有时间戳的列表:
2.5372
4.37799
6.65301
8.09344
要使这种方法起作用,您必须拥有实现场景检测的 FFmpeg 版本。此外,您必须为阈值选择一个合适的值(0.4
在第一个命令中)。您可以尝试通过提取不同阈值的帧(然后手动检查帧)来找到最佳阈值,如下所示
ffmpeg -i input.flv \
-filter:v "select='gt(scene,0.1)',showinfo" \
-vsync 0 frames/%05d.jpg
只是为了澄清:grep [0-9.]*
不排除另一个答案中声称的整数。它匹配任何由数字和句点组成的字符序列,但它也匹配非数字,如“4.4.4”。但是,ffmpeg 不应该输出这种格式错误的时间戳。