From 858b19d7635e8228315daa2f2808b28f80fac67b Mon Sep 17 00:00:00 2001
From: Michael Hanson <mihanson@linhes.org>
Date: Tue, 10 Jul 2012 21:12:52 +0000
Subject: linhes-scripts: Add myth2mkv to convert recordings to x264/mkv.

---
 abs/core/linhes-scripts/PKGBUILD |   9 +-
 abs/core/linhes-scripts/myth2mkv | 425 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 431 insertions(+), 3 deletions(-)
 create mode 100644 abs/core/linhes-scripts/myth2mkv

diff --git a/abs/core/linhes-scripts/PKGBUILD b/abs/core/linhes-scripts/PKGBUILD
index aed756e..829694b 100644
--- a/abs/core/linhes-scripts/PKGBUILD
+++ b/abs/core/linhes-scripts/PKGBUILD
@@ -3,11 +3,12 @@
 
 pkgname=linhes-scripts
 pkgver=7
-pkgrel=40
+pkgrel=41
 pkgdesc="Various scripts that help to make LinHES, LinHES."
 arch=('i686' 'x86_64')
 license=('GPL2')
-depends=('xosd' 'cpulimit' 'screen' 'mencoder' 'tablet-encode' 'mplayer' 'normalize')
+depends=('xosd' 'cpulimit' 'screen' 'mencoder' 'tablet-encode' 'mplayer'
+         'normalize' 'handbrake-cli' 'mkvtoolnix')
 url="http://linhes.org/"
 install="linhes-scripts.install"
 source=(
@@ -49,6 +50,7 @@ upgrade_linhes_script.sh
 find_orphans.py
 acl_fix_fstab.py 
 stop_xss.sh
+myth2mkv
 )
 
 build() {
@@ -101,4 +103,5 @@ md5sums=('f56985b2d602e11dc1e10d3e7848b2a5'
          'f454faeabfa153b10389a9a3bfd51c4a'
          'd8838461af9d446a1fd7e7883fdc75d1'
          'cc9cdabcdfc969c2829b58c0e513488c'
-         '54a478660d0f8150fe10112a9ecf2740')
+         '54a478660d0f8150fe10112a9ecf2740'
+         '980423e07c8c6ffd0ea1bf9a1959fdc2')
diff --git a/abs/core/linhes-scripts/myth2mkv b/abs/core/linhes-scripts/myth2mkv
new file mode 100644
index 0000000..5035748
--- /dev/null
+++ b/abs/core/linhes-scripts/myth2mkv
@@ -0,0 +1,425 @@
+#!/bin/bash
+#
+# Convert video to AVC-1 / h264
+#
+# version 0.25-001
+#
+# Prerequisites:
+#   - mythtv >= 0.25
+#   - handbrake-cli
+#   - mplayer
+#   - mkvtoolnix
+#
+# Arguments
+# $1 must be the directory/file of the recording
+# $2 must be chanid
+# $3 must be starttime
+# $4 must be title
+# $5 must be subtitle
+# $6 must be jobid
+# $7 must be quality of encode
+#
+# As a MythTV user job:
+# myth2mkv "%DIR%/%FILE%" "%CHANID%" "%STARTTIME%" "%TITLE%" "%SUBTITLE%" "%JOBID%" HQ|MQ|LQ
+
+########################
+#                      #
+# Adjustable variables #
+#                      #
+########################
+
+OUTDIR=/myth/video
+LOGPATH=/var/log/mythtv
+LOGFILE=${LOGPATH}/myth2mkv-$$.log
+
+# TMPDIR is for large transient files
+TMPDIR=/myth/tmp
+
+# x264 tuning:
+# Tune x264 based on content. Valid options for TUNING are:
+# film, animation, grain, stillimage, psnr, ssim, fastdecode, zerolatency
+# Separate multiple options with a comma. DEFAULT: none
+TUNING=""
+
+# Custom cropping. Useful if you have a 4:3 image in a HD frame or if
+# HandBrake's autocrop smarts fail you.
+# Crop 240 pixels off the left and right for 4:3 image in 1920x1080 frame
+# Crop 160 pixels off the left and right for 4:3 image in 1280x720 frame
+# <T:B:L:R>
+# i.e. 0:0:240:240
+# Default: In HQ: CROP="0:0:0:0" (no cropping).
+#          IN MQ and LQ: autocrop.
+CROP=""
+
+# Force custom output resolution.
+# Default: Keep same resolution as input file (less any cropping).
+WIDTH=""
+HEIGHT=""
+
+# Force use/non-use of deinterlacing filter. Y|N|G (Yes, No, Guess)
+# Default: G - Guess based on source resolution.
+# If the source video width is 1920, 1440, 852, 704, 640 or 528 pixels
+# "G" will deinterlace the video. Change to "Y" to force use of deinterlacing
+# filter or to "N" to NOT use deinterlace filter no matter the resolution.
+DEINT="G"
+
+############################
+#                          #
+# End adjustable variables #
+#                          #
+############################
+
+if [[ -e $HOME/.mythtv/mysql.txt ]] ; then
+  . $HOME/.mythtv/mysql.txt
+else
+  DBHostName=${DBHostName:-"localhost"}
+  DBUserName=${DBUserName:-"mythtv"}
+  DBPassword=${DBPassword:-"mythtv"}
+  DBName=${DBName:-"mythconverg"}
+fi
+
+if [[ ! -d ${TMPDIR} ]] ; then
+  mkdir -p ${TMPDIR}
+fi
+
+if [[ ! -d ${OUTDIR} ]] ; then
+  mkdir -p ${OUTDIR}
+fi
+
+#------FUNCTIONS---------------
+update_comment()
+# Arg_1 = COMMENT
+{
+if [ ${NO_JOBID} -eq 0 ]; then
+   SQL_CMD="update jobqueue set comment=\"${1}\" where id=\"${JOBID}\";"
+   `${MYSQLCMD} "${SQL_CMD}"`
+fi
+}
+
+check_background_progress()
+# check handbrake progress in background
+{
+while [ `tail -2 ${STATUSFILE} | grep -c "^HandBrake has exited"` = 0 ]
+do
+    sleep 10
+    check_myth_jobcmds
+    pass=`tail -1 ${STATUSFILE} | egrep -o -e 'task [0-9]' | tail -1 | sed 's/task\ //g'`
+    prog_percent=`tail -1 ${STATUSFILE} | egrep -o -e '[0-9]*\.[0-9]. %' | tail -1 | sed 's/\ %//g'`
+    current_FPS=`tail -1 ${STATUSFILE} | egrep -o -e 'avg [0-9.]*\.[0-9]* fps' | tail -1 | sed -e 's/avg\ //g' -e 's/\ fps//g'`
+    current_ETA=`tail -1 ${STATUSFILE} | egrep -o -e 'ETA [0-9.][0-9.]h[0-9.][0-9.]m[0-9.][0-9.]s' | tail -1`
+    if [ -n "$prog_percent" ]; then
+        echo "Pass ${pass}, ${prog_percent}% @ ${current_FPS} fps. ${current_ETA}"
+        update_comment "Pass ${pass} of 2, ${prog_percent}% @ ${current_FPS} fps. ${current_ETA}"
+    fi
+    sleep 10
+done
+}
+
+check_myth_jobcmds()
+# check the myth database for stop pause or resume commands
+{
+if [[ ${NO_JOBID} -eq 0 ]] ; then
+    CURRENT_CMD=`${MYSQLCMD} "select cmds from jobqueue where id = \"${JOBID}\";"`
+    case "${CURRENT_CMD}" in
+        # JOB_RUN
+        0) ;;
+        # JOB_PAUSE
+        1) `${MYSQLCMD} "update jobqueue set status=\"6\" where id=\"${JOBID}\";"`
+           kill -s STOP ${handbrake_pid} ;;
+        # JOB_RESUME
+        2) `${MYSQLCMD} "update jobqueue set status=\"4\" where id=\"${JOBID}\";"`
+           `${MYSQLCMD} "update jobqueue set cmds=\"0\" where id=\"${JOBID}\";"`
+           kill -s CONT ${handbrake_pid} ;;
+        # JOB_STOP
+        4) `${MYSQLCMD} "update jobqueue set status=\"5\" where id=\"${JOBID}\";"`
+           `${MYSQLCMD} "update jobqueue set cmds=\"0\" where id=\"${JOBID}\";"`
+           kill -9 ${handbrake_pid} ${command_pid}
+           clean_up_files
+           echo "Encode Cancelled" >> ${LOGFILE}
+            `${MYSQLCMD} "update jobqueue set status=\"320\" where id=\"${JOBID}\";"`
+           exit ;;
+    esac
+fi
+}
+
+get_info_for_hb() {
+# Collect some info about source file
+
+/usr/bin/mplayer -nolirc -identify -frames 0 "${HBINPUTFILE}" \
+  2>/dev/null 1>"${IDFILE}"
+
+VIDEOW=$( grep ID_VIDEO_WIDTH= "${IDFILE}" | awk -F= '{ print $NF }' )
+FPS=$( grep ID_VIDEO_FPS= "${IDFILE}" | awk -F= '{ print $NF }' )
+
+# HandBrake does not like a framerate of 29.970, so let's drop the 0
+if [[ ${FPS} = "29.970" ]] ; then
+  FPS="29.97"
+fi
+
+# A rough guestimation that if the video width is 1920, 1440, 852, 704, 640 or
+# 528 pixels it is probably interlaced.
+if [[ ${DEINT} = Y ]] ; then
+  DEINT="-d slow"
+else
+  if [[ ${DEINT} = N ]] ; then
+    DEINT=""
+  else
+    if [[ ${VIDEOW} = 1920 || ${VIDEOW} = 1440 || ${VIDEOW} = 852 || \
+        ${VIDEOW} = 704 || ${VIDEOW} = 640 || ${VIDEOW} = 528 ]] ; then
+      DEINT="-d slow"
+    else
+      DEINT=""
+    fi
+  fi
+fi
+
+if [[ -n ${DEINT} ]] ; then
+  if [[ ${QUALITY} = LQ ]] ; then
+    DEINT="-d fast"
+  fi
+fi
+
+if [[ -n ${TUNING} ]] ; then
+  TUNING="--x264-tune ${TUNING}"
+fi
+
+if [[ -n ${CROP} ]] ; then
+  CROP="--crop ${CROP}"
+fi
+
+if [[ -n ${WIDTH} ]] ; then
+  WIDTH="-w ${WIDTH} -X ${WIDTH}"
+fi
+
+if [[ -n ${HEIGHT} ]] ; then
+  HEIGHT="-l ${HEIGHT} -Y ${HEIGHT}"
+fi
+
+if [[ ${QUALITY} = HQ ]] ; then
+  if [[ -n ${CROP} ]] ; then
+    CROP="--crop ${CROP}"
+  else
+    CROP="--crop 0:0:0:0"
+  fi
+  HB_OPTS="-o ${TMPFILE} -f mkv -m -e x264 ${TUNING} -x b-adapt=2:rc-lookahead=50 -b 5000 -2 -T ${WIDTH} ${HEIGHT} -r ${FPS} --cfr ${CROP} ${DEINT} -a 1 -E copy -s 1"
+else
+  if [[ ${QUALITY} = LQ ]] ; then
+    HB_OPTS="-o ${TMPFILE} -f mkv -m -e x264 ${TUNING} -b 1250 ${WIDTH} ${HEIGHT} -r ${FPS} --pfr ${CROP} ${DEINT} -a 1 -E lame -B 128 -Q 8 -6 stereo -s 1"
+  else
+    # Fallback to "MQ"
+    HB_OPTS="-o ${TMPFILE} -f mkv -m -e x264 ${TUNING} -b 2500 -2 -T ${WIDTH} ${HEIGHT} -r ${FPS} --pfr ${CROP} ${DEINT} -a 1 -E lame -B 256 -Q 3 -6 stereo -s 1"
+  fi
+fi
+}
+
+get_handbrake_pid()
+{
+process_name=""
+i1=1
+while [ "${process_name}" != "found" ]; do
+   handbrake_pid=`expr ${handbrake_pid} + 1`
+   i1=`expr ${i1} + 1`
+   if [ "`ps ${handbrake_pid} | grep HandBrakeCLI | sed 's_.*\(HandBrakeCLI\).*_\1_'`" = "HandBrakeCLI" ]; then
+      process_name="found"
+   fi
+   if [ ${i1} -gt 20 ]; then
+      break
+   fi
+done
+}
+
+tag_file() {
+DATE=`date`
+
+# Create a tag file here
+echo "<?xml version='1.0' encoding='ISO-8859-1'?>" > "${TAG_FILE}"
+echo ""  >> "${TAG_FILE}"
+echo "<!DOCTYPE Tags SYSTEM 'matroskatags.dtd'>" >> "${TAG_FILE}"
+echo "" >> "${TAG_FILE}"
+echo "<Tags>" >> "${TAG_FILE}"
+echo " <Tag>" >> "${TAG_FILE}"
+echo "   <Simple>" >> "${TAG_FILE}"
+echo "     <Name>TITLE</Name>" >> "${TAG_FILE}"
+echo "     <String>${TITLE}</String>" >> "${TAG_FILE}"
+echo "     <Simple>" >> "${TAG_FILE}"
+echo "       <Name>SUBTITLE</Name>" >> "${TAG_FILE}"
+echo "       <String>${SUBTITLE}</String>" >> "${TAG_FILE}"
+echo "       <Simple>" >> "${TAG_FILE}"
+echo "         <Name>SUMMARY</Name>" >> "${TAG_FILE}"
+echo "         <String>${DESCR}</String>" >> "${TAG_FILE}"
+echo "       </Simple>" >> "${TAG_FILE}"
+echo "       <Simple>" >> "${TAG_FILE}"
+echo "         <Name>DATE_RELEASED</Name>" >> "${TAG_FILE}"
+echo "         <String>${OAD}</String>" >> "${TAG_FILE}"
+echo "       </Simple>" >> "${TAG_FILE}"
+echo "     </Simple>" >> "${TAG_FILE}"
+echo "   </Simple>" >> "${TAG_FILE}"
+echo "   <Simple>" >> "${TAG_FILE}"
+echo "       <Name>ENCODER</Name>" >> "${TAG_FILE}"
+echo "       <String>HandBrakeCLI ${HBCLIVER}</String>" >> "${TAG_FILE}"
+echo "   </Simple>" >> "${TAG_FILE}"
+echo "   <Simple>" >> "${TAG_FILE}"
+echo "       <Name>DATE_TAGGED</Name>" >> "${TAG_FILE}"
+echo "       <String>${DATE}</String>" >> "${TAG_FILE}"
+echo "   </Simple>" >> "${TAG_FILE}"
+echo " </Tag>" >> "${TAG_FILE}"
+echo "</Tags>" >> "${TAG_FILE}"
+
+# Add tag info into MKV file
+echo "Adding tag info to ${TITLE} - ${SUBTITLE} ..." >> ${LOGFILE}
+
+/usr/bin/mkvpropedit -r ${LOGFILE} -t all:"${TAG_FILE}" "${TMPFILE}"
+}
+
+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 ${STATUSFILE} 2> /dev/null
+unlink ${IDFILE} 2> /dev/null
+unlink ${HB_RETURN_CODE} 2> /dev/null
+unlink ${TAG_FILE} 2> /dev/null
+}
+
+#-------MAIN SCRIPT------------
+
+# create temp filename so multiple instances won't conflict
+TMPNAME=toX264-$$
+TMPFILE=${TMPDIR}/${TMPNAME}.mkv
+TMPCUTFILE=${TMPDIR}/${TMPNAME}.mpg
+HBINPUTFILE="${1}"
+TITLE="${4}"
+SUBTITLE="${5}"
+JOBID="${6}"
+QUALITY="${7}"
+BASE=`basename ${HBINPUTFILE}`
+HBCLIVER=`pacman -Q | grep handbrake-cli | awk '{ print $NF }' | awk -F"-" '{ print $1 }'`
+STATUSFILE=/tmp/${TMPNAME}-status.log
+HB_RETURN_CODE=/tmp/${TMPNAME}-hb_return_code
+IDFILE=/tmp/${TMPNAME}-id.txt
+TAG_FILE=/tmp/${TMPNAME}.xml
+MYSQLCMD="mysql -B --skip-column-names -u ${DBUserName} -p${DBPassword} -h ${DBHostName} -D ${DBName} -e"
+OAD=`${MYSQLCMD} "select originalairdate from recorded where basename LIKE '${BASE}';"`
+DESCR=`${MYSQLCMD} "select description from recorded where basename LIKE '${BASE}';" | sed 's/\&/and/g'`
+USER=`whoami`
+
+# check if %JOBID% is passed from command line
+if [ -z ${JOBID} ]; then
+    NO_JOBID=1
+else
+    NO_JOBID=0
+fi
+
+# log file location
+CDate="`date`"
+echo "" >> ${LOGFILE}
+echo $CDate >> ${LOGFILE}
+echo "File to encode: ${HBINPUTFILE}" >> ${LOGFILE}
+echo "    --> Name: ${TITLE} - ${SUBTITLE}" >> ${LOGFILE}
+echo "        --> Temporary Files: ${TMPNAME}.*" >> ${LOGFILE}
+echo "" >> ${LOGFILE}
+
+get_info_for_hb
+ERROR=$?
+
+if [[ ${ERROR} != 0 ]] ; then
+  echo "Error parsing source file information!" >> ${LOGFILE}
+  cat ${IDFILE} >> ${LOGFILE}
+  clean_up_files
+  exit 1
+fi
+
+# start timer
+beforetime="$(date +%s)"
+
+check_myth_jobcmds
+
+# If there is a cutlist, use it:
+if [[ -n `mythutil --getcutlist --chanid "${2}" --starttime "${3}" | grep \
+  Cutlist: | awk -F": " '{ print $NF }'` ]] ; then
+  echo "Applying cutlist for ${TITLE} - ${SUBTITLE} ..." >> ${LOGFILE}
+  mythtranscode --chanid "${2}" --starttime "${3}" -m --honorcutlist \
+    -q --loglevel info --logpath "${LOGPATH}" -o "${TMPCUTFILE}"
+  mythtrans_pid=$!
+  ERROR=$?
+  HBINPUTFILE=${TMPCUTFILE}
+fi
+
+if [[ ${ERROR} != 0 ]] ; then
+  echo "MythTranscode error!" >> ${LOGFILE}
+  echo "Check ${LOGPATH}/mythtranscode.date.${mythtrans_pid}.log for mythtranscode error" >> ${LOGFILE}
+  clean_up_files
+  exit 1
+fi
+
+# run handbrake in background to do conversion
+echo "Encoding ${TITLE} - ${SUBTITLE} ..." >> ${LOGFILE}
+
+( /usr/bin/nice -n19 nohup /usr/bin/HandBrakeCLI -i ${HBINPUTFILE} ${HB_OPTS} \
+  > ${STATUSFILE} 2>&1 ; echo $? > ${HB_RETURN_CODE} ) &
+handbrake_pid=$!
+command_pid=${handbrake_pid}
+get_handbrake_pid
+
+check_background_progress
+
+if [[ `cat ${HB_RETURN_CODE}` != 0 ]] ; then
+  echo "HandBrakeCLI error!" >> ${LOGFILE}
+  cat ${STATUSFILE} >> ${LOGFILE}
+  clean_up_files
+  exit 1
+fi
+
+tag_file
+ERROR=$?
+
+if [[ ${ERROR} != 0 ]] ; then
+  echo "Error creating tag file!" >> ${LOGFILE}
+  cat ${TAG_FILE} >> ${LOGFILE}
+  clean_up_files
+  exit 1
+fi
+
+# make output filename unique and do not clobber an existing file
+# Build a final file name
+FILE=$( echo "${TITLE,,} ${OAD} ${SUBTITLE,,}" | tr -d [:punct:] | tr [:blank:] "_" | tr -s "_" )
+OUTPUTFILE="${OUTDIR}/${FILE}.mkv"
+i=1
+while [ -e "${OUTPUTFILE}" ]
+do
+    OUTPUTFILE="${OUTDIR}/${FILE}-${i}.mkv"
+    i=`expr $i + 1`
+done
+
+# move temp file to output location
+chown -v "${USER}" "${TMPFILE}" >> ${LOGFILE}
+mv -v "${TMPFILE}" "$OUTPUTFILE" >> ${LOGFILE}
+ERROR=$?
+
+if [[ ${ERROR} != 0 ]] ; then
+  echo "Error moving ${TMPFILE} to ${OUTPUTFILE} !" >> ${LOGFILE}
+  clean_up_files
+  exit 1
+fi
+
+# stop timer
+aftertime="$(date +%s)"
+seconds="$(expr ${aftertime} - ${beforetime})"
+
+if [ ${ERROR} -eq 0 ]; then
+    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}
+    `${MYSQLCMD} "update jobqueue set status = \"272\" where id = \"${JOBID}\";"`
+    update_comment "Encode Successful. Encoding Time: ${hours} hour\(s\) ${minutes} minute\(s\) ${seconds} second\(s\)"
+else
+    echo "ERROR: ${ERROR}" >> ${LOGFILE}
+fi
+
+# Clean up
+clean_up_files
-- 
cgit v0.12

