I'm using ffmpeg for extracting key frames from a video. This is the command:
ffmpeg -i test2.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpegHow can I get the index of each key frame extracted in the video? For example, for the first I-frame, the index would be 0, for the second, it would be 24, etc.
72 Answers
Like @dstob mentioned, you can use ffprobe to get the I-frames and their associated information. ffprobe comes with some of the static builds on the download page and can be built from source as well.
This is assuming you're on Linux/Unix:
Extract frames and frame types
ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1The grep command filters lines with I in them, and counts their index (using the -n option). The cut command selects the first column of the output only (the index). Note that this index is 1-based, not 0-based.
Rename output files based on index
You can actually pipe these indices to a list:
ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1 > frame_indices.txtThen make a list of all the thumbnails too:
ls -1 thumbnails*.jpeg > thumbnails.txtThen paste those two together:
paste thumbnails.txt frame_indices.txt > combined.txtThe list now contains the name of the thumbnail and the index. Perform a rename based on that:
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.txtThe above will rename thumbnail-01.jpeg to thumbnail-0.jpeg. Note that there is no zero-padding on the output index. If you want to zero-pad it to, say, 5 digits, use printf:
newIndex=$(printf '%05d' $(echo $index - 1 | bc))On Windows, you'd do the exact same with ffprobe but parse the output differently. No idea how to perform the renaming there though.
If you wish to use FFMPEG as originally stated, You can list all or partial listing as well as create jpg with the following:
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"Remove -t 15 for no time limit or change to suit.
Remove -s 160x90 -f image2 thumbnail-%02d.jpeg or change to suit for thumbnail removal.