FFMPEG: Extracting 20 images from a video of variable length

I was trying to find the answer to this question too. I made use of radri's answer but found that it has a mistake.

ffmpeg -i video.avi -r 0.5 -f image2 output_%05d.jpg

produces a frame every 2 seconds because -r means frame rate. In this case, 0.5 frames a second, or 1 frame every 2 seconds.

With the same logic, if your video is 1007 seconds long and you need only 20 frames, you need a frame every 50.53 seconds. Translated to frame rate, would be 0.01979 frames a second.

So your code should be

ffmpeg -i video.avi -r 0.01979 -f image2 output_%05d.jpg

I hope that helps someone, like it helped me.


I know I'm a bit late to the party, but I figured this might help:

For everyone having the issue where ffmpeg is generating an image for every single frame, here's how I solved it (using blahdiblah's answer):

First, I grabbed the total number of frames in the video:

ffprobe -show_streams <input_file> | grep "^nb_frames" | cut -d '=' -f 2

Then I tried using select to grab the frames:

ffmpeg -i <input_file> -vf "select='not(mod(n,100))'" <output_file>

But, no matter what the mod(n,100) was set to, ffmpeg was spitting out way too many frames. I had to add -vsync 0 to correct it, so my final command looked like this:

ffmpeg -i <input_file> -vsync 0 -vf "select='not(mod(n,100))'" <output_file>

(where 100 is the frame-frequency you'd like to use, for example, every 100th frame)

Hope that saves someone a little trouble!