Length Script

From MythTV Official Wiki
Revision as of 23:49, 2 January 2008 by Iamlindoro (talk | contribs)

Jump to: navigation, search

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