Selecting one every n frames from a video using ffmpeg

ffmpeg

I was trying to extract one every N frames from a video using ffmpeg. I tried using this command:
ffmpeg -i input.mp4 -vf "select=not(mod(n\,10))" 1_every_10/img_%03d.jpg

I wanted to verify that it is working as expected. So I extracted all frames using:
ffmpeg -i input.mp4 -vf "select=not(mod(n\,1))" all/img_%03d.jpg

And then I tried to see if 2nd image from the first command matches image number 20 from the second command, and it didn't match. Confirmed both visually and using diff command like

diff all/img_020.jpg 1_every_10/img_002.jpg
Binary files all/img_020.jpg and 1_every_10/img_002.jpg differ

Anyone knows what could be going on? Thanks!

Best Answer

The image2 muxer defaults to constant frame rate. So if the input is, say, 30 fps, and you select every 10th frame i.e. frames with timestamp 0s, 0.33s, 0.66s.. then ffmpeg will duplicate frames to match the input rate so duplicate 9 frames for every input frame.

Way to avoid that is to set video sync method to passthrough or variable frame rate

e.g.

ffmpeg -i input.mp4 -vf "select=not(mod(n\,10))" -vsync vfr 1_every_10/img_%03d.jpg

This can potentially affect the full extraction if the input is VFR. So, use

ffmpeg -i input.mp4 -vf select -vsync vfr all/img_%03d.jpg
Related Question