Mythconvert
Contents
What is it
This script is a simple bash script which will convert a recording using HandbrakeCLI and place the output file in a specific folder. One particularity of this script is that it will respond to all mythtv commands and report the proper status and comment for the job, interfacing with the database to do so.
An understanding of HandbrakeCLI is required to configure this script although as is a mkv video with a bitrate of 1500 will be created. You can also use Handbrake presets (see Mythtv user job configuration below).
You have full control over the flow of this script via mythTV. It will respond to stop/pause/resume properly as well as report progress in mythtv and mythweb.
When the scripts encounters an error and is reported by mythTV, the user should check his temp directory for any hb.xxxx (where x is a number) left. These are temporary files left by an unclean exit of Handbrake. They can be deleted, assuming no other Handbrake instance is running.
Configuration
Requirements
HandbrakeCLI has to be installed and reachable within PATH.
Mythtv user job configuration
The user job command line should read as follow:
/yourPathTo/mythconvert.sh %JOBID% "%DIR%" "%FILE%" "%TITLE%" "%SUBTITLE%"
If you so wish you can use any Handbrake preset to encode. All you have to do is to modify the user job command to
/yourPathTo/mythconvert.sh %JOBID% "%DIR%" "%FILE%" "%TITLE%" "%SUBTITLE%" --preset=\"PRESET\"
Please note the use of the backslash before the quotation mark. This is called escaping a caracter and is necessary for the script to properly identify the preset and pass it in a usable form to HandbrakeCLI. The available presets can be listed using
HandbrakeCLI -z
or on the Handbrake website.
Script
Development idea
I tried as much as possible to keep the code clean. It should not be too hard to modify the command to be run while keeping much of the mythtv interface. As such, this script could serve as a basis for other scripts which would like to interface with mythtv properly.
On to the code
Copy this code into a file named mythconvert.sh
Make sure the user under which mythtv is running has the proper permission to run this file.
#!/bin/bash
###################################################
#
# mythconvert.sh
# A utility to convert recordings from mythtv as a user job
# using HandbrakeCLI
#
# Dominique Tardif
# March 2013
#
###################################################
#arguments order:
# 1 - %JOBID% : job id as given by mythtv
# 2- %DIR%: input directory as given by mythtv
# 3- %FILE%: input file as given by mythtv
# 4- %TITLE%: show title as given by mythtv
# 5 - %SUBTITLE%: show subtitle as given by mythtv -> this is optionnal
# In the absence of a subtitle, could also be a handbrake preset in form of --preset=\"PRESET\"
# 6 - Handbrake preset -> this is optionnal
# Should be of form --preset=\"PRESET\"
###################################################
#
# Script configuration section
#
###################################################
#Values for transcoder
#
# niceValue : nice value for encoding job. Default: 15
# transcodeOptions : command line options for handbrake.
# This will be overwritten if a handbrake preset is specified with the command --preset=\"PRESET\"
# Be sure to escape " as written : \"
# Default: --format mkv --two-pass --turbo --vb 1500
# outputExtension: Desired output file extension, without period. Default: mkv
niceValue="15"
transcodeOptions="--format mkv --two-pass --turbo --vb 1500"
outputExtension="mkv"
#Change permissions of output file if desired, set to 1 to enable
chmodON="0"
chmodMOD="644"
#Folder for output - do not add trailing slash
outputFolder="/yourOutputFolder"
#Enter mythtv database information here
dbServer="localhost"
dbUser="user"
dbPwd="password"
dbName="mythconverg"
###################################################
#
# Script internal variables - do not edit
#
###################################################
id="$1"
preset='(--preset=".*")'
inputFile="$2/$3"
outputFile=""
title="$4"
subtitle="$5"
statusStarting=3
statusRunning=4
statusStopping=5
statusPaused=6
statusErroring=8
statusDone=256
statusFinished=272
statusErrored=304
currentCommand=""
newCommand=""
encodePID=""
# getCommand - get command set by mythtv in jobqueue table
# Parameters : none
getCommand()
{
newCommand=$(echo "SELECT cmds FROM jobqueue WHERE id='$id'" | mysql -h $dbServer -u $dbUser --password=$dbPwd $dbName | tail -1)
}
# setStatus - sets current job status in jobqueue table
# Parameters: takes one parameter as integer - see internal variables for status definitions
setStatus()
{
status=$1
echo "UPDATE jobqueue SET status='$status' WHERE id='$id'" | mysql -h $dbServer -u $dbUser --password=$dbPwd $dbName
}
# updateComment - changes the comment for the running job in jobqueue table
# Parameters: takes one parameter as string
updateComment()
{
comment=$1
echo "UPDATE jobqueue SET comment='$comment' WHERE id='$id'" | mysql -h $dbServer -u $dbUser --password=$dbPwd $dbName
}
# startEncode - starthe actual encoding when getCommand returns 0
# Parameters: none
startEncode()
{
setStatus $statusStarting
updateComment "starting mv2vids job with id $id"
nice -n $niceValue HandBrakeCLI $transcodeOptions -i "$inputFile" -o "$outputFile" > /tmp/mv2vids.log 2> /tmp/mv2vids.err.log &
encodePID=$!
setStatus $statusRunning
updateComment "Job id $id is running"
}
# stopEncode - stop the encoding when getCommand returns 4
# Parameters: none
stopEncode()
{
setStatus $statusStopping
updateComment "stoping mv2vids job with id $id"
kill -15 $encodePID
tryKill=$?
if [ $tryKill -eq -1 ]
then error "Could not cleanly terminate process"
fi
rm /tmp/mv2vids.log
setStatus $statusDone
updateComment "Job stopped"
}
# pause - pause the encoding when getCommand returns 1
# Parameters: none
pause()
{
kill -19 $encodePID
setStatus $statusPaused
updateComment "Job id $id is paused"
}
# resume - resume the encoding when getCommand returns 2
# Parameters: none
resume()
{
setStatus $statusStarting
updateComment "Resuming mv2vids job with id $id"
kill -18 $encodePID
setStatus $statusRunning
updateComment "Job id $id is running"
}
# error - exits script when error
# Parameters: takes one string to send back to mythtv as error message
error()
{
setStatus $statusErroring
updateComment "mv2vids job with id $id encountered an error"
setStatus $statusErrored
updateComment "$1"
if [ -n "$encodePID" ]
then kill -9 $encodePID
fi
#Un-comment next line to remove log file
#Kept by default to see if there is an error
#rm /tmp/mv2vids.log
exit 1
}
# restartEncode - stops current job and restart it
# Parameters: none
restart()
{
setStatus $statusStopping
updateComment "mv2vids job with id $id is stoping for a restart"
stopEncode
startEncode
}
# main - controls job flow
# Parameters: takes two parameters
# 1 - Recording title
# 2 - Recording subtitle
main()
{
getCommand
currentCommand=$newCommand
if [ $currentCommand -eq "0" ] #Verify if job is set to run in mythtv database
then
if [ -n "$2" ] #Verify if there is a subtitle attached to the job, set outputFile accordingly
then
outputFile="$outputFolder/$1 - $2.$outputExtension"
startEncode
else
if [ -n "$1" ]
then
outputFile="$outputFolder/$1.$outputExtension"
startEncode
else
error "Not enough parameters, should have ID,DIR,FILE,TITLE,SUBTITLE(optional). Check job configuration in mythtv"
fi
fi
else error "Job $id not set to run in jobqueue"
fi
#Main control loop - checks if process is running and if command change in mythtv database
kill -0 $encodePID
jobRunning=$?
while [ $jobRunning -eq 0 ]
do
getCommand
currentCommand=$newCommand
case "$currentCommand" in
"0" )
progress=$(strings /tmp/mv2vids.log | tail -1 | grep "" | tail -1)
updateComment "$progress"
;;
"4" )
stopEncode
exit 0
;;
"1" )
pause
;;
"2" )
resume
;;
esac
sleep 10
kill -0 $encodePID
jobRunning=$?
done
setStatus $statusFinished
updateComment "Job successful"
if [ "$chmodON" -eq "1" ]
then chmod $chmodMOD $outputFile
fi
exit 0
}
#Check is user entered --preset and overwrite default transcodeOptions
if [ -n "$6" ]
then
if [[ $6 =~ $preset ]]
then transcodeOptions="$6"
fi
else
if [ -n "$5" ]
then
if [[ $5 =~ $preset ]]
then
transcodeOptions="$5"
subtitle=""
fi
fi
fi
#This line is simply to start the main function, passing title and subtitle as arguments
main "$title" "$subtitle"
Dommtardif 16:06, 27 March 2013 (UTC)