Alex Rivera | Logout

FFMPEG: Extracting 20 images from a video of variable length

Asked 2011-12-30T12:22:10.897
20

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

Edit
Report

2 Answers

18

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!

answered 2012-10-01T01:21:07.147
5

In general, ffmpeg processes frames as they come, so anything based on the total duration/total number of frames requires some preprocessing.

I'd recommend writing a short shell script to get the total number of frames using something like

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

and then use the select video filter to pick out the frames you need. So the ffmpeg command would look something like

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

except that instead of every hundredth frame, 100 would be replaced by the number calculated in the shell script to give you 20 frames total.

answered 2012-01-09T23:56:03.130

Your Answer