Length Script
From MythTV
This script will generate accurate lengths for all movies in your MythVideo directory. Even with IMDB, many movies come back with lengths of zero minutes. Personally, I also have many television episodes archived in MythVideo. In an attempt to make my metadata more accurate, I wrote this script.
Thanks to siXy and Marcus Brown (mzb) in #mythtv-users for helping me simplify this script.
#!/bin/bash
#
# Script to automate setting of video lengths in mythtv.
#
# Searches for all MythVideo files with length of "0."
# Generates a list, and pipes each file through an
# mplayer -identify "filename." Inserts each length
# back into the database. This script needs slight
# babysitting as, if mplayer cannot play the file
# properly, it will go into a loop. In my MythVideo
# of ~500 files, I had to set lengths four times to
# get the script to complete. These files were all
# .m2ts files from Blu-Ray discs. If your files are
# all relatively standard, this should be unnecessary.
#
# Originally written by Robert McNamara (robert.mcnamara ATSIGN gmail.com)
# Contributions and code improvment by Marcus Brown
#
### Define the next five items. ###
# Myth Database Name
DBNAME=$1
# Myth DB User
DBUSER=$2
# Myth DB Password
DBPASSWORD=$3
# Where do your movies live? (Root MythVideo Directory)
MOVIEHOME=$4
# Most people have their mysql server on their localhost
SQLSERVER=$5
### Change nothing below this point. ###
DEBUG=9
## Define our SQL Commands
SQL_DETAILS="-u$DBUSER -h$SQLSERVER -p$DBPASSWORD $DBNAME"
ZERO_LENGTH="SELECT filename FROM videometadata WHERE length = 0 AND filename LIKE \"$MOVIEHOME%\""
UPDATE_LENGTH='UPDATE videometadata SET length = \"$LENGTH\" WHERE filename = \"$videofile\" LIMIT 1'
## End of definitions
trap 'forcequit' INT KILL TERM
dprint () {
level=$1
if [ $level -le $DEBUG ]
then
shift
while [ $level -gt 0 ]
do
echo -n " " >&2
let "level--"
done
echo -e "$*" >&2
fi
}
cleanup () {
[ -x "$filefifo" ] && exec 6<&-
[ -f "$filefifo" ] && rm -f "$filefifo"
exit 1
}
forcequit () {
dprint -1 "Forced quit ... cleaning up."
cleanup
exit 1
}
#########################
#
# Main
#
# Generate file list
filefifo="$(mktemp)"
rm -f "$filefifo"
mkfifo "$filefifo"
exec 6<> "$filefifo"
mysql $SQL_DETAILS -e "$ZERO_LENGTH;" | grep -v ^filename$ >&6
echo "EOF" >&6
# Loop through videos
while read -u6 videofile && [ "$videofile" != "EOF" ]
do
if [ -n "$videofile" ]
then
dprint 2 "Processing: \"$videofile\""
# Calculate length of video
TOTAL_SECONDS="$(
mplayer -vo null -ao null -frames 0 -identify "$videofile" 2>/dev/null |
grep "^ID_LENGTH" | sed -e 's%ID_LENGTH=%%'
)"
TOTAL_SECONDS="${TOTAL_SECONDS:-0}"
dprint 5 "Length: $TOTAL_SECONDS secs"
# convert to minutes (round off to nearest minute)
#LENGTH="$(perl -e "print eval(join(' ',@ARGV)).qq{};" "$TOTAL_SECONDS/60" | awk '{print int($1+0.5)}')"
LENGTH="$[ ( (${TOTAL_SECONDS%.*} * 100) + 3000 ) / 6000 ]"
dprint 4 "Length: $LENGTH mins"
# Update database
if [ $LENGTH -gt 0 ]
then
dprint 7 "$(eval echo "mysql $SQL_DETAILS -e \'$UPDATE_LENGTH\;\'")"
if eval "mysql $SQL_DETAILS -e \"$UPDATE_LENGTH;\""
then
dprint 3 "Database updated"
else
dprint -1 "Error updating database! Exiting"
cleanup
exit 1
fi
else
dprint 6 "Unable to calculate length of video."
fi
fi
done
cleanup
exit 0
