3

I'm looking for a nice short easy way to create a series of thumbnails for any given video file. I'm almost there using ffmpeg, here's what I have:

ffmpeg -i /tmp/video.avi -r 1 -ss 60 -r 1 foo-%03d.jpeg`

The only problem is that this takes a shot every second and I'd like to make it every minute or so. I tried setting the -r value to 1/60 or .02 to no avail.

For reference, here's the old script I was using that only worked for some files:

#!/bin/bash
# grab a screenshot every 60 seconds
file=$1
orig_dir=`pwd`
mins=`exiftool "$file" | grep "Duration" | awk -F : '{print $2}' | grep --only-matching '[0-9]*'`
dir="$file-screenshots"
mkdir "$dir"
cd "$dir"
mplayer -vo png -vf screenshot -sstep 60 -frames $mins -ao null "../$file"
cd "$orig_dir"

This doesn't have to be on the command line, it's just that it always ends up being easiest.

3

See the ffmpeg manpage. You want -vframes:

-vframes number
Set the number of video frames to record.

Also see this example of someone doing the same thing. The original message notes that -r doesn't seem to work properly with arguments less than one. Instead, the suggestion is to use this kind of commandline to grab one frame (where X is some time to seek forward in the file):

ffmpeg -ss X -i input.movie.file -an -vframes 1 ouput.png

Then use shell scripting to loop that and auto-generate X based on (a) how many frames you want to grab and (b) how long the video is. Since your old example script already finds (b), (a) is the only input needed:

# generate NFRAMES frames in a movie 90 minutes long

mins=$(exiftool "$file" | grep "Duration" | awk -F : '{print $2}' | grep --only-matching '[0-9]*')
dir="$file-screenshots"
mkdir "$dir"

for i in $(seq 1 $NFRAMES);
do
  ffmpeg -ss $(echo "$i * $mins" | bc -l) -i "$file" -an -vframes 1 "$dir/$i.png";
done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.