summaryrefslogtreecommitdiffstats
path: root/abs/core/linhes-scripts/myth2fuze
diff options
context:
space:
mode:
Diffstat (limited to 'abs/core/linhes-scripts/myth2fuze')
-rwxr-xr-xabs/core/linhes-scripts/myth2fuze318
1 files changed, 318 insertions, 0 deletions
diff --git a/abs/core/linhes-scripts/myth2fuze b/abs/core/linhes-scripts/myth2fuze
new file mode 100755
index 0000000..9e8fc3c
--- /dev/null
+++ b/abs/core/linhes-scripts/myth2fuze
@@ -0,0 +1,318 @@
+#!/bin/bash
+# convert recording to avi compatable with San Disk Sansa Fuze
+# Based on and/or inspired by myth2xvid, the video4fuze project:
+# http://code.google.com/p/video4fuze
+# and the fuzemux project:
+# http://code.google.com/p/fuzemux
+#
+# version 0.2
+#
+# usage:
+# first parameter must be %DIR%/%FILE% of the recording
+# second parameter must be the %TITLE% for the output filename
+# third parameter must be the %SUBTITLE% for the output filename
+# fourth parameter must be %CHANID% if you set USECUTLIST=Y
+# fifth parameter must be %STARTTIME% for USECUTLIST=Y and output filename
+# sixth parameter must be %JOBID% for the User Job status to be updated
+# in MythTV
+# In the mythtv setup screen invoke this script like this:
+# MYTHTV User Job Command:
+# /usr/LH/bin/myth2fuze "%DIR%/%FILE%" "%TITLE%" "%SUBTITLE%" "%CHANID%" "%STARTTIME%" "%JOBID%"
+
+# options:
+USECUTLIST=Y # Y or N
+
+# check prerequesites
+for APP in {fuzemux,mencoder,ffmpeg,mythcommflag,mythtranscode,mysql}; do
+ /usr/bin/which ${APP} &>/dev/null
+ ERROR=$?
+ if [ $ERROR -ne 0 ]; then
+ echo "${APP} not found in your PATH! Aborting! ERROR: ${ERROR}" >> ${LOGFILE}
+ update_status 304
+ update_comment "${APP} not found in your PATH! Aborting! Exit status: ${ERROR}"
+ exit 1
+ fi
+done
+
+# where the converted video is stored
+OUT_DIR=/myth/video/fuze
+
+# Ensure output directory exists
+if [ ! -d ${OUT_DIR} ] ; then
+ mkdir -p -m777 ${OUT_DIR}
+fi
+
+# database settings
+BACKEND_HOSTNAME=${BACKEND_HOSTNAME:-"localhost"}
+DBUSERNAME=${DBUSERNAME:-"mythtv"}
+DBPASSWORD=${DBPASSWORD:-"mythtv"}
+SQLCMD="mysql -u ${DBUSERNAME} --password=${DBPASSWORD} -h ${BACKEND_HOSTNAME} mythconverg -e"
+
+# create temp filename so multiple instances won't conflict
+TMPNAME=toFUZE-$$
+TMPDIR=/myth/tmp
+TMPFILE=${TMPDIR}/${TMPNAME}.avi
+TMPCUTFILE=${TMPDIR}/${TMPNAME}.mpg
+MENINPUTFILE=${1}
+TWOPASSFILE=/tmp/${TMPNAME}-2pass.log
+STATUSFILE=/tmp/${TMPNAME}-status.log
+MENCODER_RETURN_CODE=/tmp/${TMPNAME}-mencoder_return_code
+MENCODER_RETURN_CODE_2=/tmp/${TMPNAME}-mencoder_return_code_2
+
+# Ensure temp directory exists
+if [ ! -d ${TMPDIR} ] ; then
+ mkdir -p -m777 ${TMPDIR}
+fi
+
+#------FUNCTIONS---------------
+update_comment()
+# Arg_1 = COMMENT
+{
+if [ ${NO_JOBID} = 0 ]; then
+ `${SQLCMD} "update jobqueue set comment=\"${1}\" where id=\"${JOBID}\";"`
+fi
+}
+
+update_status()
+# Arg_1 = status code
+{
+if [ ${NO_JOBID} = 0 ]; then
+ `${SQLCMD} "update jobqueue set status=\"${1}\" where id=\"${JOBID}\";"`
+fi
+}
+
+check_background_progress()
+# check mencoder progress in background
+# Arg_1 = PROGRESS CALCULATION
+{
+while [ `tail -1 ${STATUSFILE} | grep -cE "^Audio stream:|^Video stream:"` = 0 ]
+do
+ sleep 10
+ check_myth_jobcmds
+ current_status=`tail -1 ${STATUSFILE} | grep "([ 0-9]\{1,\}%)"`
+ prog_percent=`echo ${current_status} | sed 's_.*(\([ 0-9][ 0-9]\)%).*_\1_'`
+ current_FPS=`echo ${current_status} | sed 's_.*\([ 0-9][ 0-9].[ 0-9][ 0-9]\)fps.*_\1_'`
+ if [ -n ${prog_percent} ]; then
+ prog_percent=`expr ${prog_percent} / ${1}`
+ echo "${prog_percent}% Completed @ ${current_FPS} fps"
+ update_comment "${prog_percent}% Completed @ ${current_FPS} fps"
+ fi
+ sleep 10
+done
+}
+
+check_myth_jobcmds()
+# check the myth database for stop pause or resume commands
+{
+if [ ${NO_JOBID} = 0 ]; then
+ CURRENT_CMD=`${SQLCMD} "select cmds from jobqueue where id=\"${JOBID}\";" | sed '/[0-9]/!d'`
+ case ${CURRENT_CMD} in
+ # JOB_RUN
+ 0) ;;
+ # JOB_PAUSE
+ 1) update_status 6
+ kill -s STOP ${mencoder_pid} ;;
+ # JOB_RESUME
+ 2) update_status 4
+ `${SQLCMD} "update jobqueue set cmds=\"0\" where id=\"${JOBID}\";"`
+ kill -s CONT ${mencoder_pid} ;;
+ # JOB_STOP
+ 4) update_status 5
+ `${SQLCMD} "update jobqueue set cmds=\"0\" where id=\"${JOBID}\";"`
+ kill -9 ${mencoder_pid} ${command_pid}
+ clean_up_files
+ echo "Encode Cancelled" >> ${LOGFILE}
+ update_status 320
+ exit ;;
+ esac
+fi
+}
+
+get_mencoder_pid()
+{
+process_name=""
+i1=1
+while [ "$process_name" != "found" ]; do
+ if [ "`ps ${mencoder_pid} | grep mencoder | sed 's_.*\(mencoder\).*_\1_'`" = "mencoder" ]; then
+ process_name="found"
+ else
+ mencoder_pid=`expr ${mencoder_pid} + 1`
+ fi
+ i1=`expr $i1 + 1`
+ if [ $i1 -gt 20 ]; then
+ break
+ fi
+done
+}
+
+run_fuzemux()
+# Remux avi to fuze compatable avi
+{
+/usr/bin/nice -n19 /usr/bin/fuzemux ${TMPFILE} ${OUTPUTFILE} >> ${LOGFILE} || return 1
+}
+
+create_thumbnail()
+# Create a thumbnail image for the fuze
+{
+/usr/bin/nice -n19 /usr/bin/ffmpeg -y -v -1 -i ${OUTPUTFILE} -t 1 -ss 3 \
+-s 224x176 -f image2 ${OUTPUTFILE%.*}.thm >> ${LOGFILE}
+}
+
+clean_up_files()
+# clean up left over files
+{
+unlink ${TMPFILE} 2> /dev/null
+unlink ${TMPCUTFILE} 2> /dev/null
+unlink ${TMPCUTFILE}.map 2> /dev/null
+unlink ${TWOPASSFILE} 2> /dev/null
+unlink ${TWOPASSFILE}.tmp 2> /dev/null
+unlink ${STATUSFILE} 2> /dev/null
+unlink ${MENCODER_RETURN_CODE} 2> /dev/null
+unlink ${MENCODER_RETURN_CODE_2} 2> /dev/null
+}
+
+#-------MAIN SCRIPT------------
+
+# check if %JOBID% is passed from command line
+JOBID=${6}
+if [ -z ${JOBID} ]; then
+ NO_JOBID=1
+else
+ NO_JOBID=0
+fi
+
+# log file location
+LOGFILE=/var/log/mythtv/myth2fuze.log
+CDate="`date`"
+echo "" >> ${LOGFILE}
+echo ${CDate} >> ${LOGFILE}
+echo "File to encode: ${MENINPUTFILE} Name: ${2} - ${3}" >> ${LOGFILE}
+
+# start timer
+beforetime="$(date +%s)"
+
+check_myth_jobcmds
+
+# check if using cutlist
+if [ ${USECUTLIST} = Y ]; then
+ MYTHCOMMFRAMES=$( mythcommflag --getcutlist -f ${MENINPUTFILE} | grep 'Cutlist:' | cut -d \ -f 2 )
+ if [ -n "$MYTHCOMMFRAMES" ]; then
+ echo "Extracting Cutlist..." >> ${LOGFILE}
+ update_comment "Extracting Cutlist"
+ /usr/bin/nice -n19 /usr/bin/mythtranscode --chanid ${4} --starttime ${5} --outfile ${TMPCUTFILE} --mpeg2 --honorcutlist
+ MENINPUTFILE=${TMPCUTFILE}
+ fi
+fi
+
+# run mencoder in background to do 1st pass conversion
+echo "Encoding 1st Pass for the Fuze..." >> ${LOGFILE}
+( /usr/bin/nice -n19 /usr/bin/mencoder ${MENINPUTFILE} -passlogfile \
+${TWOPASSFILE} -ffourcc DX50 -ofps 20 \
+-vf pp=li,expand=:::::224/176,scale=224:176,harddup -ovc lavc \
+-lavcopts vcodec=mpeg4:vbitrate=683:vmax_b_frames=0:keyint=15:turbo:vpass=1 \
+-nosound -o /dev/null > ${STATUSFILE} 2>&1 ; echo $? > \
+${MENCODER_RETURN_CODE} ) &
+mencoder_pid=$!
+command_pid=${mencoder_pid}
+get_mencoder_pid
+
+check_background_progress "2"
+
+if [ `cat ${MENCODER_RETURN_CODE}` -ne 0 ]; then
+ echo "Mencoder pass #1 exited with error ${MENCODER_RETURN_CODE}. Encoding failed!"
+ update_status 304
+ update_comment "ERROR: Mencoder pass #1 exited with error ${MENCODER_RETURN_CODE}"
+ clean_up_files
+ exit 1
+fi
+
+# run mencoder in background to do 2nd pass conversion
+echo "Encoding 2nd Pass for the Fuze..." >> ${LOGFILE}
+( /usr/bin/nice -n19 /usr/bin/mencoder ${MENINPUTFILE} -passlogfile \
+${TWOPASSFILE} -ffourcc DX50 -ofps 20 \
+-vf pp=li,expand=:::::224/176,scale=224:176,harddup -ovc lavc \
+-lavcopts vcodec=mpeg4:vbitrate=683:vmax_b_frames=0:keyint=15:vpass=2 \
+-srate 44100 -af resample=44100:0:1,format=s16le -oac mp3lame \
+-lameopts cbr:br=128 -o ${TMPFILE} > ${STATUSFILE} 2>&1 ; echo $? \
+> ${MENCODER_RETURN_CODE_2} ) &
+mencoder_pid=$!
+command_pid=${mencoder_pid}
+get_mencoder_pid
+
+check_background_progress "2 + 50"
+
+if [ `cat ${MENCODER_RETURN_CODE_2}` -ne 0 ]; then
+ echo "Mencoder pass #1 exited with error ${MENCODER_RETURN_CODE}. Encoding failed!"
+ update_status 304
+ update_comment "ERROR: Mencoder pass #1 exited with error ${MENCODER_RETURN_CODE_2}"
+ clean_up_files
+ exit 1
+fi
+
+# make output filename unique, remove punctuation and "special" characters,
+# replace spaces with underscores and force lowercase names
+OAD=$( echo ${5} | cut -b 1-8 )
+FILENAME=$( echo "${2} ${OAD} ${3}" | tr -d '[:punct:]' \
+ | tr -s '[:blank:]' '[_]' | tr '[:upper:]' '[:lower:]' )_fuze.avi
+
+OUTPUTFILE=${OUT_DIR}/${FILENAME}
+ERROR=$?
+
+if [ ${ERROR} -ne 0 ]; then
+ echo "Setting output file name exited with error ${ERROR}" >> ${LOGFILE}
+ update_status 304
+ update_comment "ERROR: Setting output file name exited with error ${ERROR} Job failed!"
+ clean_up_files
+ exit 1
+fi
+
+run_fuzemux
+ERROR=$?
+
+if [ ${ERROR} -ne 0 ]; then
+ echo "Fuzemux exited with error ${ERROR}" >> ${LOGFILE}
+ update_status 304
+ update_comment "ERROR: Fuzemux exited with error ${ERROR} Job Failed!"
+ clean_up_files
+ exit 1
+fi
+
+# ensure mythtv owns the final avi
+chown mythtv ${OUTPUTFILE}
+ERROR=$?
+
+if [ ${ERROR} -ne 0 ]; then
+ echo "Changing ownership of avi to mythtv exited with error ${ERROR}"
+ update_status 304
+ update_comment "ERROR: Changing ownership of avi to mythtv exited with error ${ERROR} Job failed!"
+ clean_up_files
+ exit 1
+fi
+
+create_thumbnail
+
+# ensure mythtv owns the thumbnail
+chown mythtv ${OUTPUTFILE%.*}.thm
+ERROR=$?
+
+if [ ${ERROR} -ne 0 ]; then
+ echo "Changing ownership of thumbnail to mythtv exited with error ${ERROR}"
+ update_status 304
+ update_comment "ERROR: Changing ownership of thumbnail to mythtv exited with error ${ERROR} Job failed!"
+ clean_up_files
+ exit 1
+fi
+
+# stop timer
+aftertime="$(date +%s)"
+seconds="$(expr $aftertime - $beforetime)"
+ echo "File Encoded Successfully: ${OUTPUTFILE}" >> ${LOGFILE}
+ hours=$((seconds / 3600))
+ seconds=$((seconds % 3600))
+ minutes=$((seconds / 60))
+ seconds=$((seconds % 60))
+ echo "Encoding took $hours hour(s) $minutes minute(s) $seconds second(s) @ $current_FPS fps." >> ${LOGFILE}
+ update_status 272
+ update_comment "Encode Successful. Encoding Time: $hours hour(s) $minutes minute(s) $seconds second(s)"
+
+clean_up_files