I'm currently implementing /video/thumbnail functionality for transload.it and did some research on how to implement it.

First I set out to create a single thumbnail which was very easy:

ffmpeg -i intro.mov -vframes 1 -s 320x240 -ss 10 thumb.jpg

This takes a video file (-i intro.mov) and extract a single frame (-vframes 1) with 320x240px (-s 320x240) at an offset of 10 seconds (-ss 10) and saves it as thumb.jpg.

So far so good. But we actually want to offer the ability to take multiple thumbnails (like 8) in 1/8th increments of the video playtime. My initial idea was that there had to be more efficient way then calling up ffmpeg 8 times, and indeed I found one:

ffmpeg -i intro.mov -r 1/10 -s 320x240 thumb_%03d.jpg

This command works the same as the one above, except that it tries to set the frame rate to 1/10 (-r 1/10 = 1 frame every 10 seconds) and saves the results as thumb_000.jpg, thumb_001.jpg, thumb_002.jpg etc. Unfortunately I could not get it to produce the exact results I wanted. I would always end up with the first frame being captured twice, and the frame rate I set would be off by 2-3 seconds.

So I hopped to IRC and asked #ffmpeg for help. Dark_Shikari (one of the crazy people who build the best video codec in the world) was kind enough to help me.

It turns out that the offset parameter (-ss) needs to be set before the input parameter (-i). That will cause ffmpeg to seek to that position in the stream *without* decoding it and in fact skipping anything but key frames! This is pretty significant as performance improved from ~20 seconds for 4 thumbnails to about 2-3 seconds.

So my final setup is pretty much like this. First I find out the video duration by running:

midentify intro.mov

This gives me all kinds of useful information including the length of the video: