About me

My name is Rich Jerrido and I am the person behind www.outsidaz.org I am a geek hailing from the city of brotherly love. I started this blog a couple of years back as a dumping place for a lot of working knowledge of mine that I could have available online regardless of where I was. Over time it has evolved into being a full-fledged blog, complete with RSS feeds, comments, and pictures.When I am not hacking on computers for profit, I hack on them for fun.Read more about me »

New Year….New Desktop

New Year….New Desktop Featured Work

Keep in touch

RSS Feed Twitter Facebook Delicious

Subscribe via Email

Screencap Generation via FFmpeg and ImageMagick

October 26th, 2009 by RichJ received 1 Comment »

Since the move to Linux on my Home Theater PC’s. I’ve needed a new Screen capture utility to create preview images for usage in XBMC. After looking around a bit, and not finding anything I like, I decided to whip something up using some bash. What I needed what a script that would take a screenshot of a movie at some ‘x’ number of intervals and then glue them together into one image. Also, added to the image, I wanted some of the file’s metadata such as its length, resolution and codec.


Requirements:

  • Bash – Included with your distro
  • bc – Should be included in your distro or its repositiories
  • ImageMagick – Should be included in your distro or its repositiories
  • FFMpeg – Usually not included with any distro due to licensing/codec concerns. On Fedora, this is found in the RPMFusion repo

Installation & Usage

  • Save the script (here) below somewhere and make it executable
  • Edit the parameters to your liking (Mainly the MAXTHUMB, THUMBSIZE, OUTPUT_DIR, & WORK_DIR values)
  • Execute: make_movie_thumb.sh “/path/to/your/movie.avi”

Output:

And the code:

#!/bin/bash

#Number of Thumbnails to be created. It is advisable to use an number that makes a perfect square such as 9,16,25
MAXTHUMB=25
#Size of thumbnails
THUMBSIZE="160x120"
#output directory
OUTPUT_DIR="/home/rjerrido/Desktop/thumbs/x/y/z"
#working directory
WORK_DIR="/tmp/thumbnail"

#clear work directory before each run
/bin/rm -rf "$WORK_DIR"
#create work dir if non-existent
[ -w $WORK_DIR ] || mkdir -p $WORK_DIR
#create output dir if non-existent
[ -w $OUTPUT_DIR ] || mkdir -p $OUTPUT_DIR
## These variables gather some information about the video file
duration_seconds=`ffmpeg -i "$1" 2>&1 | grep "Duration" | cut -f4 -d" " | cut -f3 -d":" | cut -f1 -d","`
duration_minutes=`ffmpeg -i "$1" 2>&1 | grep "Duration" | cut -f4 -d" " | cut -f2 -d":"`
duration_hours=`ffmpeg -i "$1" 2>&1 | grep "Duration" | cut -f4 -d" " | cut -f1 -d":"`
runTime=`echo "$duration_seconds + 60*$duration_minutes + 3600*$duration_hours" | bc`
size=`ffmpeg -i "$1" 2>&1 | /bin/grep "Video:" | cut -f 3 -d ","`
codec=`ffmpeg -i "$1" 2>&1 |  /bin/grep "Video:" | cut -f 1 -d "," | cut -f 3 -d ":"`


MYFILE=`basename "$1"`
echo "*** You specified an input file of -> " "$1"
echo "*** You specified a working directory of -> " "$WORK_DIR"
echo "*** You specified a output directory of -> " "$OUTPUT_DIR"
FILEBASENAME=${MYFILE%.*}
INTERVAL=`echo "$runTime / $MAXTHUMB" | bc`
for numthumb in `seq 1 ${MAXTHUMB}`;
do
        CURR_INTERVAL=`echo "$numthumb * $INTERVAL" | bc`
        ffmpeg -y -ss $CURR_INTERVAL -vcodec mjpeg -vframes 1 -an -f rawvideo -s $THUMBSIZE  "$WORK_DIR""/""$FILEBASENAME""$numthumb"".jpg" -i "$1" &>/dev/null
done

LABEL="Filename: ""$MYFILE"" Codec: ""$codec"" Size: ""$size"" Length: "$duration_hours"":""$duration_minutes"":""$duration_seconds""
echo "*** I will apply the following label -> " $LABEL
montage -borderwidth 0 -geometry $THUMBSIZE"+0+0" "$WORK_DIR""/""$FILEBASENAME""*.jpg"  "$OUTPUT_DIR""/""$FILEBASENAME"".jpg"
echo "*** Final screencap image is stored here -> " "$OUTPUT_DIR""/""$FILEBASENAME"".jpg"
convert -gravity North -splice 0x18 -background Plum -annotate +0+2 "$LABEL" "$OUTPUT_DIR""/""$FILEBASENAME"".jpg" "$OUTPUT_DIR""/""$FILEBASENAME"".jpg"

Todo:

  • Add some switches to make most of the options configurable
  • Put this script in a Subversion repo somewhere
  • Clean up some of the code.
Posted under: Linux


One Response to “Screencap Generation via FFmpeg and ImageMagick”

  1. Ryan Long says:

    Hey, Rich,

    Thanks for sharing this script. I tried it out, and it worked well, but I decided to refactor it and improve upon it a bit. Namely, I wanted to make sure that the thumbnails are not being pulled out of proportion. I also made it a bit more efficient by having ffmpeg do all the work of extracting the thumbnails at the correct interval. In doing so, I’ve avoided calling ffmpeg for each thumbnail, which was taking a bit longer for each thumbnail, as it had to seek through the file all the way each time.

    I’ve put my script up on Github, I hope it’s okay with you to utilize your code and share it. If not, I will happily take it down. I have, of course credited you and linked to this page in the script. You can find my code at http://github.com/rtlong/video-gallery

    BTW, and I know this was in 2009, but since you mentioned it: if you are not yet using git for source control, I will highly recommend you try it out. It’s got a bit of a learning curve, especially coming from SVN, but it’s so worth it! It just kicks the pants off of every other VCS out there (except Mercurial, which, IMO, it’s basically tied with)


Leave a Reply