结合使用场景过滤器(用于检测场景变化)和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不应输出此类格式不正确的时间戳。