#!/bin/bash # Thomas Lewiner, http://www.carva.org/thomas.lewiner # Matmidia Lab, Dept of Mathematics, PUC-Rio de Janeiro # September 16th, 2009 # # video thumbnail generator # using bash, ffmpeg and ImageMagick # # usage: # ./videothumb.bash file.avi # # edit the settings in this file following the comments # works with any video file readable by ffmpeg # # width of a single frame (without shading margins) width=128 ; # shadow size shadow=5 ; # rounded corner size round=6 ; # frame shift: uncomment here and comment the marked line for a fixed shift between pages # shift=50; # automatic page shift to fit the thumbnail in a given width total_width=450; # second skip: get a frame every $sec_skip seconds sec_skip=19; for vid in "$1" ; do # extract the total time of the video in seconds let "total_time=$(ffmpeg -i ${vid} 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed -e 's/\([0-9]*\):\([0-9]*\):\([0-9]*\).*/\1 * 3600 + \2 * 60 + \3/')" ; # extract rounded frames from vid (starting from the second frame of the sequence, set time to 0 for the first frame) count=0; time=$sec_skip; while [ $time -lt $total_time ] ; do ffmpeg -y -i ${vid} -vcodec png -f rawvideo -vframes 1 -an -ss ${time} thumb.png 2> /dev/null ; convert -resize $width -matte -virtual-pixel transparent -channel A -blur 0x$round -threshold 50% +channel thumb.png thumbs-$(printf '%03d' ${count}).png ; let "time += $sec_skip" ; let "count += 1"; done ; rm thumb.png ; # add shadows for p in thumbs-*.png ; do convert -page +${shadow}+${shadow} $p -matte \( +clone -background black -shadow 60x${shadow}+${shadow}+${shadow} \) +swap -background none -mosaic ${p/.png/_shadow.png} && rm $p ; done ; # frame shift: comment the next line for a fixed shift between frames let "count=$count/2"; let "shift=($total_width - $width - $shadow)/($count - 1)"; echo "$vid lasts $total_time seconds, leading to 2x$count retained frames (each $sec_skip seconds), set to $width px extent each, rounded by $round px, shadowed of $shadow px and shifted by $shift px"; # compose the final images offset=0 ; cmd="" ; for ((c=0; c<${count}; c+=1)) do cmd="-page +${offset}+0 thumbs-$(printf '%03d' ${c})_shadow.png $cmd" ; let "offset += $shift" ; done ; convert $cmd -background transparent -layers mosaic "${vid/[.]*/_thumb1.png}"; offset=0 ; cmd="" ; for ((c=${count}; c<=2*${count}; c+=1)) do cmd="-page +${offset}+0 thumbs-$(printf '%03d' ${c})_shadow.png $cmd" ; let "offset += $shift" ; done ; convert $cmd -background transparent -layers mosaic "${vid/[.]*/_thumb2.png}"; rm thumbs-*_shadow.png ; done ;