2 minute read

*Edit: This version will produce errors when using a file list. See this single for a more reliable way.

I have been searching for a while for a way to create a video preview from the command line in Linux. Not just a simple screen shot, but an animated gif of screen shots throughout the video. My thinking is that a screen shot of a video at a random time may not look suspicious, but the next frame may be something illegal. Essentially for a video I would like to take 4 - 6 screen shots regardless of the duration, compile these into an animated gif, and display the preview.

First I have been looking at my options:
I am on Debian 'Lenny', and while vlc might look like a good option, the lenny release is stuck at 0.8.6. The newest release is 1.1.4 (I think), but in 0.8.6 the --start-time switch is ignored. I tried upgrading using sid, but ran into a bunch of problems and decided not to mess with it.

I looked into mplayer which created screen shots, but I could not easily find how to divide the duration into 6, and quickly take the snap shot at those times. Basically I just got a bunch of sequential snapshots, and when I put them together would make the video again. I could delete some in the middle to get the desired effect, but thought there had to be an easier way. Also mplayer gui always wanted to start, and I did not want that.

Finally ffmpeg - with ffmpeg and imagemagick I was able to get something similar to what I wanted.

First the ffmpeg line


ffmpeg -i $file -ss 120 -t 120 -r 0.05 -s 90x90 f%d.jpg


What this does is takes the input video file '$file', starts at 2 minutes (-ss 120), runs for 2 minutes (-t 120), sets a very low frame rate (-r 0.05), re-sizes the preview to 90x90px (-s 90x90), and names all the output images f#.jpg (f%d.jpg). Rather than calculating the duration, making the frame rate low gives a similar effect. I will write duration calculation later.

So once we run that we have a directory full of *.jpg files. We need to roll them into one animated gif. For this I use imagemagick. I have seen a lot of people who are using gimp for this. I love gimp, but imagemagick is easier converting a bunch of jpgs to an animated gif.


convert -delay 100 -loop 0 f*.jpg $file.gif

*adapted from here

This will group all the jpg files in a loop with approx a 1 second pause per image. Works a treat!

Here is the first preview I tested (have only tested with .ogm and .mp4 so far)
Video Screenshot Preview gif - FLCL


Here is my full bash script to do the processing. It takes a file name as an argument - the loop is to deal with file names with spaces.


#!/bin/bash
echo "$1" | while read file
do
if [ -f "$file" ]; then
echo "Creating preview of $file"
ffmpeg -i "$file" -ss 120 -t 120 -r 0.05 -s 90x90 f%d.jpg
fn=$(echo ${file// /}) # Remove spaces in filename
convert -delay 100 -loop 0 f*.jpg $fn.gif
rm *.jpg
fi
done
exit 0