Length Script
From MythTV Official Wiki
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