1 | #!/bin/bash
|
2 |
|
3 | # Written by Bob Igo from the MythTV Store at http://MythiC.TV
|
4 | # with contributions from TJC and Sarah Hayes
|
5 | # Email: bob@stormlogic.com
|
6 | #
|
7 | # If you run into problems with this script, please send me email
|
8 |
|
9 | # This is alpha code to auto-generate thumbnails for previews in MythVideo.
|
10 | # It won't currently work on some filenames that have spaces in them.
|
11 | # It's surely just a matter of escaping or quoting, but I have yet to find
|
12 | # the right incantation.
|
13 |
|
14 | # example usage:
|
15 | # find -L /myth/video -wholename '*.covers' -prune -o -name '*.resume' -o -type f -exec screenshooter.sh -v {} \;
|
16 |
|
17 | # limitations:
|
18 | # --
|
19 | # In an MBE/SBE/FE setup this might get the settings for the wrong machine...
|
20 | # The script has no AI to know if a grabbed frame is useful to identify the video, only that it was able to grab it.
|
21 | # Doesn't clean up after itself if videos are deleted, though MythTV may do this on its own.
|
22 | # Minimum theoretical compatible video length is 4 seconds. Shorter videos will not work with this version.
|
23 | # Surely more limitations I can't think of because it's my baby :)
|
24 |
|
25 | Usage() {
|
26 | echo "USAGE:"
|
27 | echo `basename $0` "-v PATHNAME [-s SECONDS] [-c] [-b HOSTNAME] [-u USERNAME] [-p PASSWORD] [-o]"
|
28 | echo "-v: pathname to Video"
|
29 | echo "-s: number of Seconds to skip before capturing (270 by default)"
|
30 | echo "-c: Clobber any previous screenshot found for this video (off by default)"
|
31 | echo "-b: mysql server (Backend) hostname (localhost by default)"
|
32 | echo "-u: mysql Username (mythtv by default)"
|
33 | echo "-p: mysql Password (mythtv by default)"
|
34 | echo "-o: verbOse mode (off by default)"
|
35 | echo "-x: check for valid video eXtension (off by default)"
|
36 | echo
|
37 | echo "EXAMPLE: $0 -v /myth/video/HDTV/shuttle.mpg -c -s 30"
|
38 | exit 3
|
39 | }
|
40 |
|
41 | if [ -z $1 ]; then
|
42 | Usage
|
43 | fi
|
44 |
|
45 | V_MISSING=1
|
46 |
|
47 | while getopts "v:sbupochx" FLAG ; do
|
48 | case "$FLAG" in
|
49 | v) VIDEO_PATHNAME="$OPTARG"
|
50 | V_MISSING=0;;
|
51 | s) SKIPAHEAD="$OPTARG";;
|
52 | c) CLOBBER=1;;
|
53 | b) BACKEND_HOSTNAME="$OPTARG";;
|
54 | u) DBUSERNAME="$OPTARG";;
|
55 | p) DBPASSWORD="$OPTARG";;
|
56 | o) VERBOSE=1;;
|
57 | x) EXTENSION_CHECK=1;;
|
58 | *) Usage;;
|
59 | esac
|
60 | done
|
61 |
|
62 | if [ $V_MISSING == 1 ]; then
|
63 | Usage
|
64 | fi
|
65 |
|
66 | # Declaring Variables here and assigning sensible defaults.
|
67 |
|
68 | # SKIPAHEAD is the number of seconds to skip ahead before starting the frame capture.
|
69 | # Set it to an arbitrary value if none is specified.
|
70 | SKIPAHEAD=${SKIPAHEAD:-"270"}
|
71 | BACKEND_HOSTNAME=${BACKEND_HOSTNAME:-"localhost"}
|
72 | DBUSERNAME=${DBUSERNAME:-"mythtv"}
|
73 | DBPASSWORD=${DBPASSWORD:-"mythtv"}
|
74 | # Defaults to quiet.
|
75 | VERBOSE=${VERBOSE:-0}
|
76 | # Unless otherwise told, do not clobber existing cover files.
|
77 | CLOBBER=${CLOBBER:-0}
|
78 | # Unless otherwise told, do not check the file extension against
|
79 | # MythTV's list of registered video file types.
|
80 | EXTENSION_CHECK=${EXTENSION_CHECK:-0}
|
81 |
|
82 | VIDEO_CAPTURE_HOME=$(mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -sNBe "select data from settings where value='VideoArtworkDir' limit 1")
|
83 | if [ ! -d "$VIDEO_CAPTURE_HOME" ] ; then
|
84 | echo "Directory $VIDEO_CAPTURE_HOME does not exist, nowhere to put the screen shot!"
|
85 | echo "Have you configured MythVideo yet?"
|
86 | exit 1
|
87 | fi
|
88 |
|
89 | VIDEO_HOME=$(mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -sNBe "select data from settings where value='VideoStartupDir' limit 1")
|
90 | VIDEO_HOME=(${VIDEO_HOME//:/ });
|
91 | VIDEO_HOME_COUNT=${#VIDEO_HOME[@]}
|
92 | for (( i=0; i<${VIDEO_HOME_COUNT}; i++ ));
|
93 | do
|
94 | if [ ! -d "${VIDEO_HOME[${i}]}" ] ; then
|
95 | echo "Directory ${VIDEO_HOME[${i}]} does not exist, nowhere to put the screen shot!"
|
96 | echo "Have you configured MythVideo yet?"
|
97 | exit 1
|
98 | fi
|
99 | done
|
100 |
|
101 | VIDEO_FILENAME=$(basename "$VIDEO_PATHNAME")
|
102 | VIDEO_EXTENSION=${VIDEO_FILENAME##*.}
|
103 | # Since we cron'd lets first make sure the validity of the file
|
104 | if [ "$EXTENSION_CHECK" == "1" ]; then
|
105 | EXCHECK=$(mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -sNBe "select f_ignore from videotypes where extension=\"$VIDEO_EXTENSION\";")
|
106 | #excheck returns blank, it found nothing.
|
107 | if [ "$EXCHECK" == "" ]; then
|
108 | if [ "$VERBOSE" == "1" ]; then
|
109 | echo "$VIDEO_EXTENSION does not appear to be a valid media file, skipping."
|
110 | fi
|
111 | exit 1
|
112 | else
|
113 | # It is valid, but should we ignore it. If so then excheck will equal 1.
|
114 | if [ "EXCHECK" == "1" ]; then
|
115 | if [ "$VERBOSE" == "1" ]; then
|
116 | echo "$VIDEO_EXTENSION is set to ignore."
|
117 | fi
|
118 | exit 1
|
119 | fi
|
120 | # It is valid, it's not set to ignore.
|
121 | if [ "$VERBOSE" == "1" ]; then
|
122 | echo "$VIDEO_EXTENSION appears in the Database, checking further."
|
123 | fi
|
124 | EXCHECK=$(mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -sNBe "select title from videometadata where filename=\"$VIDEO_PATHNAME\";")
|
125 | #Right, the file is supposed to be playable. Has it been imported to the Db yet?
|
126 | if [ "$EXCHECK" == "" ] ; then
|
127 | if [ "$VERBOSE" == "1" ]; then
|
128 | echo "$VIDEO_FILENAME does not exist in the database."
|
129 | fi
|
130 | exit 1
|
131 | # If you decide you want the system to 'auto import' the video then comment out
|
132 | # the exit line and uncomment the rest of it. Bewarned, this is sucky SQL at
|
133 | # the best but will give sensible defaults.
|
134 | #
|
135 | # if [ "$VERBOSE" == "1" ]; then
|
136 | # echo "Importing $VIDEO_FILENAME in to database."
|
137 | # fi
|
138 | # mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -sNBe "insert into videometadata (intid, title, director, plot, rating, inetref, year, userrating, length, showlevel, filename, coverfile, childid, browse, playcommand, category) values (' ', '$VIDEO_FILENAME', 'Unknown', 'Unknown', 'NR', '00000000', 1895, 0.0, 0, 1, '$VIDEO_PATHNAME', 'No Cover', -1, 1, ' ', 0);"
|
139 | fi
|
140 | fi
|
141 | fi
|
142 |
|
143 | if [ "$CLOBBER" -eq 0 ]; then
|
144 | # Since we're not clobbering, first check to see if this video already has a coverfile entry in MySQL:
|
145 | SQL_CMD="select coverfile from videometadata where filename=\"$VIDEO_PATHNAME\";"
|
146 | CURRENT_COVERFILE=`mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -B -e "$SQL_CMD" | tail -1`
|
147 |
|
148 | if [[ "$CURRENT_COVERFILE" != "" ]] && [[ "$CURRENT_COVERFILE" != "No Cover" ]]; then
|
149 | # there's already a cover file for this video
|
150 | if [ "$VERBOSE" == "1" ]; then
|
151 | echo "$VIDEO_FILENAME has cover file, skipping."
|
152 | fi
|
153 | exit 2
|
154 | fi
|
155 | fi
|
156 |
|
157 |
|
158 | # Swap the video file extension for png. Should work assuming the extension only appears ONCE!
|
159 | VIDEO_CAPTURE_PATHNAME="$VIDEO_CAPTURE_HOME/$VIDEO_FILENAME.png"
|
160 |
|
161 | # How many frames of video to capture. We'll grab the last frame as our screenshot.
|
162 | if [ "$VIDEO_EXTENSION" == "m4v" ]; then
|
163 | FRAMES_TO_CAPTURE="90"
|
164 | SHOTFILE="000000"$FRAMES_TO_CAPTURE".png"
|
165 | else
|
166 | FRAMES_TO_CAPTURE="05"
|
167 | fi
|
168 |
|
169 | SHOTFILE="000000"$FRAMES_TO_CAPTURE".png"
|
170 | VIDEO_STATS="/tmp/screenshooter_video_stats.txt"
|
171 |
|
172 | cd /tmp
|
173 |
|
174 | # The video we're processing may be shorter than SKIPAHEAD seconds.
|
175 | # Keep trying to capture until we find a SKIPAHEAD value within the length of the video.
|
176 | # Give up if we reach 0 seconds.
|
177 | while [ ! -f "$SHOTFILE" ]; do
|
178 | /usr/bin/mplayer -ss $SKIPAHEAD -vf scale=640:-2 -ao null -vo png -quiet -frames $FRAMES_TO_CAPTURE -identify "$VIDEO_PATHNAME" &> $VIDEO_STATS &
|
179 | TIMEOUT=9
|
180 |
|
181 | # Some video formats will play audio only. This loop gives the above command 20 seconds to
|
182 | # finish, otherwise it gets killed.
|
183 | while [ -n "`ps -p $! --no-heading`" ]; do
|
184 | TIMEOUT=$(expr $TIMEOUT - 1)
|
185 | if [ "$TIMEOUT" -le 0 ]; then
|
186 | kill -9 $!
|
187 | break
|
188 | fi
|
189 | sleep 1
|
190 | done
|
191 |
|
192 | SKIPAHEAD=$(expr $SKIPAHEAD / 2)
|
193 | if [ "$SKIPAHEAD" -le 0 ]; then
|
194 | break
|
195 | fi
|
196 | done
|
197 |
|
198 | if [ -f "$SHOTFILE" ]; then
|
199 | # Now, the video_capture is taken, and the name of the shot is in $SHOTFILE
|
200 | # Rename it and move it to the place where video_captures live.
|
201 | /bin/mv -f "$SHOTFILE" "$VIDEO_CAPTURE_PATHNAME"
|
202 | /bin/rm -f 000000*png
|
203 | chown mythtv: "$VIDEO_CAPTURE_PATHNAME"
|
204 |
|
205 | # We've got the shotfile nailed, now calculate video run length.
|
206 | VIDEO_LENGTH_IN_SECONDS=`grep ID_LENGTH $VIDEO_STATS | awk -F'=' '{print $2}'`
|
207 | VIDEO_LENGTH_IN_INTEGER_SECONDS=${VIDEO_LENGTH_IN_SECONDS/%.*/}
|
208 | if [ $VIDEO_LENGTH_IN_INTEGER_SECONDS -lt 60 ]; then
|
209 | VIDEO_LENGTH_IN_MINUTES="1"
|
210 | else
|
211 | VIDEO_LENGTH_IN_MINUTES=$(expr $VIDEO_LENGTH_IN_INTEGER_SECONDS / 60)
|
212 | fi
|
213 |
|
214 | SQL_CMD="update videometadata set length=\"$MIN_LENGTH\" where filename=\"$VIDEO_PATHNAME\";"
|
215 | mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -e "$SQL_CMD"
|
216 |
|
217 |
|
218 | # put the screenshot pathname and any runlength info into videometadatatable
|
219 |
|
220 | # Pre-escape any single or double quotes for the SQL command.
|
221 |
|
222 | VIDEO_CAPTURE_PATHNAME=`echo $VIDEO_CAPTURE_PATHNAME | sed -e "s/'/\\\'/g" -e 's/"/\\\"/g' `
|
223 | VIDEO_PATHNAME=`echo $VIDEO_PATHNAME | sed -e "s/'/\\\'/g" -e 's/"/\\\"/g' `
|
224 | SQL_CMD="update videometadata set coverfile=\"$VIDEO_CAPTURE_PATHNAME\", length=\"$VIDEO_LENGTH_IN_MINUTES\" where filename=\"$VIDEO_PATHNAME\";"
|
225 |
|
226 | mysql -u $DBUSERNAME --password=$DBPASSWORD -h $BACKEND_HOSTNAME mythconverg -e "$SQL_CMD"
|
227 | else
|
228 | echo "No image could be captured from $VIDEO_PATHNAME"
|
229 | exit 1
|
230 | fi
|