我正在使用 ffmpeg 从视频中提取关键帧。这是命令:
ffmpeg -i test2.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
如何获取视频中提取的每个关键帧的索引?例如,对于第一个 I 帧,索引为 0,对于第二个,索引为 24,等等。
答案1
就像@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
该grep
命令过滤I
其中的行,并计算其索引(使用选项-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
然后列出所有缩略图:
ls -1 thumbnails*.jpeg > thumbnails.txt
然后将两者粘贴在一起:
paste thumbnails.txt frame_indices.txt > combined.txt
列表现在包含缩略图的名称和索引。根据该名称执行重命名:
while read -r thumbnail index; do
newIndex=$(echo $index - 1 | bc) # subtract 1 from the index
mv -- "$thumbnail" "thumbnail-$newIndex.jpeg" # rename file
done < combined.txt
以上将重命名thumbnail-01.jpeg
为thumbnail-0.jpeg
。请注意,输出索引上没有零填充。如果您想将其零填充为 5 位数字,请使用printf
:
newIndex=$(printf '%05d' $(echo $index - 1 | bc))
在 Windows 上,您可以执行完全相同的操作,ffprobe
但解析输出的方式不同。不过不知道如何在那里执行重命名。
答案2
如果您希望按照最初说明的方式使用 FFMPEG,您可以列出全部或部分列表以及使用以下内容创建 jpg:
ffmpeg.exe \
-i "C:\Users\UserName\Desktop\jpegs and list\VideoName.mp4" \
-t 15 \
-vf select="eq(pict_type\,PICT_TYPE_I)" \
-vsync 2 \
-s 160x90 \
-f image2 thumbnails-%02d.jpeg \
-loglevel debug 2>&1| for /f "tokens=4,8,9 delims=. " %d in ('findstr "pict_type:I"') do echo %d %e.%f>>"keyframe_list.txt"
-t 15
无时间限制地删除或更改以适应。删除-s 160x90 -f image2 thumbnail-%02d.jpeg
或更改以适应缩略图删除。