25

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.jpeg

How 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.

7
  • possible duplicate of superuser.com/questions/669716/…
    – user236012
    Commented Mar 4, 2015 at 16:03
  • Look into using ffprobe then post process the output to get the index?
    – dstob
    Commented Mar 4, 2015 at 17:36
  • @dstob could you explain more about what you mean ? as I'm new to ffmpeg. Commented Mar 4, 2015 at 19:11
  • @LordNeckbeard The frame number in the video frames, ex. the first frame of the video would be at index 0 I want to know the index of each key frame in the video frames. Commented Mar 4, 2015 at 19:16
  • You want the frame number to be printed on the thumbnail (on the image itself)?
    – llogan
    Commented Mar 4, 2015 at 20:30

2 Answers 2

28

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 1

The 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.txt

Then make a list of all the thumbnails too:

ls -1 thumbnails*.jpeg > thumbnails.txt

Then paste those two together:

paste thumbnails.txt frame_indices.txt > combined.txt

The 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.txt

The 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.

4
  • This error is displayed: 'grep' is not recognized as an internal or external command, operable program or batch file. Commented Mar 5, 2015 at 0:23
  • 2
    That's because you're on Windows. Like I said, this answer assumes Linux or Unix. You were not being more specific in your question. You can achieve the same on Windows using Cygwin or similar GNU/Linux layers for Windows.
    – slhck
    Commented Mar 5, 2015 at 9:29
  • This is a huge help, thanks. One correction: I think the indices in your first command are off by a factor of three, because there is a [FRAME] line and a [/FRAME] line for every pict_type line. Commented Dec 28, 2015 at 22:58
  • 2
    @JackO'Connor There is only one line per frame if you use the -of csv option for ffprobe. What you're describing is the default output format, though.
    – slhck
    Commented Dec 30, 2015 at 10:52
3

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.

1
  • In Windows 7 CMD, this fails at the \. Changing \ to ^ causes a fail at the :I" . Do you have a version that works on Windows?
    – ChrisJJ
    Commented Dec 18, 2019 at 9:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .