Q:

FFMPEG: Extracting 20 images from a video of variable length

I've browsed the internet for this very intensively, but I didn't find what I needed, only variations of it which are not quite the thing I want to use.
I've got several videos in different lengths and I want to extract 20 images out of every video from start to the end, to show the broadest impression of the video.
So one video is 16m 47s long => 1007s in total => I have to make one snapshot of the video every 50 seconds.
So I figured using the -r switch of ffmpeg with the value of 0.019860973 (eq 20/1007) but ffmpeg tells me that the framerate is too small for it...
The only way I figured out to do it would be to write a script which calls ffmpeg with a manipulated -ss switch and using -vframes 1 but this is quite slow and a little bit off for me since ffmpegs numerates the images itself...
Any suggestions or directions?
Thanks,
Vapire

A:

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!

A:

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.

A:

You could try convert video to N number of images ?
ffmpeg -i video.avi image%d.jpg

Update:
Or extract frame every 2 seconds:
ffmepg -i video.avi -r 0.5 -f image2 output_%05d.jpg

Update:
To get the video duration:
ffmpeg -i video.avi 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//

Then, depends on your programming language, you convert it into seconds. For example, in PHP, you could do it like this:
$duration = explode(":",$time); 
$duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);

where $time is the video duration. The you can execute $duration_in_seconds / 20
ffmepg -i video.avi -r $duration_in_seconds/20 -f image2 output_%05d.jpg

