使用 ffmpeg 从视频中提取关键帧的索引

Fat*_*ifa 18 ffmpeg

我正在使用 ffmpeg 从视频中提取关键帧。这是命令:

ffmpeg -i test2.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
Run Code Online (Sandbox Code Playgroud)

如何获取视频中提取的每个关键帧的索引?例如,对于第一个 I 帧,索引将为 0,对于第二个 I 帧,索引将为 24,依此类推。

slh*_*hck 22

就像@dstob 提到的那样,您可以使用ffprobe来获取 I 帧及其相关信息。下载页面上ffprobe带有一些静态构建,也可以从源代码构建。

这是假设您使用的是 Linux/Unix:

提取帧和帧类型

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1
Run Code Online (Sandbox Code Playgroud)

grep命令过滤带有Iin 的行,并计算它们的索引(使用-n选项)。该cut命令仅选择输出的第一列(索引)。请注意,此索引是基于 1 的,而不是基于 0 的。

根据索引重命名输出文件

您实际上可以将这些索引通过管道传输到列表:

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1 > frame_indices.txt
Run Code Online (Sandbox Code Playgroud)

然后也列出所有缩略图:

ls -1 thumbnails*.jpeg > thumbnails.txt
Run Code Online (Sandbox Code Playgroud)

然后将这两个粘贴在一起:

paste thumbnails.txt frame_indices.txt > combined.txt
Run Code Online (Sandbox Code Playgroud)

该列表现在包含缩略图的名称和索引。基于此执行重命名:

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1 > frame_indices.txt
Run Code Online (Sandbox Code Playgroud)

以上将重命名thumbnail-01.jpegthumbnail-0.jpeg. 请注意,输出索引上没有零填充。如果要将其零填充为 5 位数字,请使用printf

newIndex=$(printf '%05d' $(echo $index - 1 | bc))
Run Code Online (Sandbox Code Playgroud)

在 Windows 上,您可以执行完全相同的操作,ffprobe但以不同的方式解析输出。不知道如何在那里执行重命名。

  • 那是因为您使用的是 Windows。就像我说的,这个答案假设是 Linux 或 Unix。你的问题没有更具体。您可以使用 [Cygwin](https://www.cygwin.com/) 或 Windows 的类似 GNU/Linux 层在 Windows 上实现相同的功能。 (2认同)
  • @JackO'Connor 如果您对 `ffprobe` 使用 `-of csv` 选项,则每帧只有一行。不过,您所描述的是默认输出格式。 (2认同)