screenshooter.sh

admin, 08/16/2009 11:29 am

Download (8.9 kB)

 
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