SHARE
TWEET

Bash Video Thumbnailer

julian_hughes Sep 1st, 2012 203 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # videothumbs, a simple videothumbnailer
  3. #
  4. #  Copyright (C) 2012 Julian Hughes julianhughes<at>gmailDOTcom
  5. #
  6. #  This program is free software; you can redistribute it and/or modify
  7. #  it under the terms of the GNU General Public License as published by
  8. #  the Free Software Foundation; either version 3 of the License, or
  9. #  (at your option) any later version.
  10. #
  11. #  This program is distributed in the hope that it will be useful,
  12. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. #  GNU General Public License for more details.
  15. #
  16. #  You should have received a copy of the GNU General Public License
  17. #  along with this program.  If not, see <http://www.gnu.org/licenses/>
  18. #
  19. # REQUIRES: mplayer, ffmpeg, imagemagick
  20.  
  21. #check mplayer, ffmpeg, imagemagick are installed
  22. type montage >/dev/null 2>&1 || { echo >&2 "ImageMagick is not \
  23. installed or is not in your path."; exit 1; }
  24. type mplayer >/dev/null 2>&1 || { echo >&2 "mplayer is not installed \
  25. or is not in your path."; exit 1; }
  26. type ffmpeg >/dev/null 2>&1 || { echo >&2 "ffmpeg is not installed \
  27. or is not in your path."; exit 1; }
  28.  
  29. #user options
  30. while getopts 'o:' OPTION
  31. do
  32.         case $OPTION in
  33.         o)      oflag=1
  34.                 oval=$OPTARG
  35.                 ;;
  36.         esac
  37. done
  38. shift $(($OPTIND-1))
  39.  
  40. function mpscreens ()
  41. {
  42. mplayer "$i" -noconfig all -nolirc -nojoystick -nosound -ss 5 \
  43. -sstep $STEP -vf scale=$WIDE:-2 -vo png:outdir=$OUT
  44. }
  45. function ffscreens ()
  46. {
  47. for t in {1..40}; do ffmpeg -ss $(($t*$STEP)) -i "$i" -f image2 \
  48. -vframes 1  -vf scale="$WIDE":"$H" "$OUT"/$(printf "%02d\n" "$t").png
  49. done
  50. }
  51.  
  52. for i in "$@" ;do
  53.  
  54. FILE="${i%.*}"
  55. FILE="${FILE##*/}"
  56. EXT="${i##*\.}"
  57. OUT=/tmp/thumbs
  58. INFO="$OUT"/info
  59.  
  60. mkdir "$OUT"
  61.  
  62. #set output destination. Output dir exists and writable?
  63. #defaults to movie directory.
  64. if [ $oflag ]; then
  65.         if [ ! -d "$oval" -o ! -w "$oval" ]; then
  66.         printf "\n\n\tOutput directory is not writable or doesn't exist\n\n"
  67.         exit
  68.         fi
  69.         IMGOUT=$oval/"${FILE##*/}".jpg
  70.         else
  71.         IMGOUT="${i%.*}".jpg
  72. fi
  73.  
  74. #use mplayer based capture for mkv/mpg, ffmpeg for everything else
  75. #because mplayer chokes if there is no keyframe at -ss # in avi & on
  76. # seeking some mp4.
  77. if [[ $EXT == !(mkv|MKV|mpg|MPG|mpeg|MPEG) ]] ; then
  78.         SCREENS=ffscreens
  79.         else
  80.         SCREENS=mpscreens
  81. fi
  82.  
  83. #dump movie info to text file
  84. mplayer "$i" -noconfig all -identify -novideo -vo null -ao null \
  85. -frames 0 2>/dev/null |grep AUDIO |awk -F "ID_" '{print $2}'|sort -u |\
  86. sed '/^$/d' >"$INFO" && \
  87. mplayer "$i" -noconfig all -identify -nosound -vo null -ao null \
  88. -frames 0 2>/dev/null |egrep "VIDEO|LENGTH" |awk -F "ID_" '{print $2}'|\
  89. sort -u |sed '/^$/d' >>"$INFO"
  90.  
  91. #for 4x10 images find movie length, divide by 40 for interval steps.
  92. LENGTH=$(grep LENGTH= "$INFO"|awk -F = '{print $2}')
  93. STEP="$(echo $LENGTH/40 |bc)"
  94.  
  95. #images should show correct aspect for anamorphic video, so find height
  96. #and aspect ratio and calculate displayed width, rounded to integer.
  97. A=$(grep VIDEO_ASPECT= "$INFO"  |awk -F = '{print $2}')
  98. H=$(grep VIDEO_HEIGHT= "$INFO" |awk -F = '{print $2}')
  99. WIDE="$(echo $A*$H |bc)"
  100. WIDE=$(printf "%.0f\n" $WIDE)
  101.  
  102. #get basic codec and dimension info for printing title.
  103. W=$(grep VIDEO_WIDTH= "$INFO" |awk -F = '{print $2}')
  104. VIDEO=$(grep VIDEO_FORMAT= "$INFO" |awk -F = '{print $2}')
  105. AUDIO=$(grep AUDIO_CODEC= "$INFO" |awk -F = '{print $2}')
  106. CHAN=$(grep -m 1 AUDIO_NCH= "$INFO" |awk -F = '{print $2}')
  107. TITLE="\n\n""${i##*/}""\nVideo: "$VIDEO", "$W"x"$H"\nAudio: "$AUDIO", \
  108. "$CHAN" Channels"
  109.  
  110. #dump uncompressed png images to temp dir while redirecting overly
  111. #verbose ffmpeg/mplayer output to /dev/null
  112. $SCREENS>/dev/null 2>&1
  113.  
  114. #make montage, clean up, quit.
  115. montage -mode concatenate -geometry 252x -border 1 -tile 4x \
  116. "$OUT"/*.png -title "$TITLE" "$IMGOUT" && \
  117. rm -rf "$OUT"
  118.  
  119. done
  120. exit 0
RAW Paste Data
Top