#!/bin/bash
# @(#)$Header: /home/mythtv/mythtvrep/scripts/mythnuv2mkv.sh,v 1.44 2009/03/18 20:11:57 mythtv Exp $
# Auric 2007/07/10 http://web.aanet.com.au/auric/
##########################################################################################################
#
# Convert MythRecording & MythVideo nuv or mpg files to mkv mp4 or avi.
#
######### Vars you may want to set for your environment ######################################################
# Default aspect for Myth Recording mpg files. It will try to work it out but if it can't will use this.
readonly DEFAULTMPEG2ASPECT="NA" # 4:3 or 16:9
# What to separate Title SeasonEpisode SubTitle with
readonly SEP=","
# Crop input
CROP="ON" # ON | OFF, can also change with --crop argument
# Delete recording after successful transcode. Only for transcode out of MythRecording. (Actually just sets to high priority autoexpire.)
DELETEREC="OFF" # ON | OFF, can also change with --deleterec argument
# Include denoise filter
DENOISE="OFF" # ON | OFF, can also change with --denoise argument
# Include deblock filter
DEBLOCK="OFF" # ON | OFF, can also change with --deblock argument
# Include deinterlace filter.
# SOURCENAME is ON for that source. Can have multiple. e.g. DEINTERLACE="Cabel,FTA1"
DEINTERLACE="ON" # ON | OFF | SOURCENAME,SOURCENAME can also change with --deinterlace argument.
# Include inverse Telecine filter (Experimental. Can someone from NTSC/ATSC land try this?).
# invtelecine filter is never added if deinterlace has been added.
INVTELECINE="OFF" # ON | OFF, can also change with --invtelecine argument.
# number passes
PASS="two" # one | two, can also change with --pass argument
# number of threads. Only used by lavc and xvid (x.264 auto calculates threads)
THREADS=1
# avi encoder lavc or xvid
AVIVID="lavc" # lavc | xvid, can also change with --contype=avi,xvid argument
# container
CONTYPE="mkv" # mkv | mp4 | avi, can also change with --contype argument or name of script.
# mkv audio encoder aac or ogg
MKVAUD="aac" # aac | ogg, can also change with --contype=mkv,ogg argument
# add your own filters if you want
POSTVIDFILTERS=""	#must include , at end
ENDVIDFILTERS=""	#must include , at end
##########################################################################################################
USAGE='mythnuv2mkv.sh [--jobid=%JOBID%] [--contype=avi|mkv|mp4] [--quality=low|med|high|480|576|720|1080] [--pass=one|two] [--denoise=ON|OFF] [--deblock=ON|OFF] [--deleterec=ON|OFF] [--crop=ON|OFF] [--deinterlace=ON|OFF|SOURCENAME] [--invtelecine=ON|OFF] [--maxrunhours=int] [--findtitle=string] [--copydir=directory] "--chanid=chanid --starttime=starttime" | file ...
Must have either --chanid=chanid and --starttime=starttime or a plain filename. These can be mixed. e.g. -
mythnuv2mkv.sh --chanid=1232 --starttime=20071231235900 video1 video2 --chanid=1235 --starttime=20071231205900
--jobid=%JOBID%
        Add this when run as a User Job. Enables update status in the System Status Job Queue screen and the Job Queue Comments field in MythWeb. Also enables stop/pause/resume of job.
--contype=avi|mkv|mp4 (default name of script. e.g. mythnuv2mkv.sh will default to mkv. mythnuv2avi.sh will default to avi)
	(Note Videos staying in MythRecord will always default to avi)
	avi - Video mpeg4 Audio mp3 (--contype=avi,xvid will use xvid instead of lavc)
	mkv - Video h.264 Audio aac (--contype=mkv,ogg will use ogg Vorbis Audio)
	mp4 - Video h.264 Audio aac
--quality=low|med|high|720|1080 (default med) Mostly affects resolution.
	low  - 448x336(4:3) or 592x336(16:9)
	med  - 512x384(4:3) or 624x352(16:9)
	high - 528x400(4:3) or 656x368(16:9)
	480  - 640x480(4:3) or 848x480(16:9)
	576  - 768x576(4:3) or 1024x576(16:9)
	720  - 1280x720(16:9) (You probably need VDAPU to play this)
	1080 - 1920x1088(16:9) (You probably need VDAPU to play this)
--pass=one|two (default two)
	--quality --pass and --contype can be passed as any argument and will only take effect on files after them.
	e.g. mythnuv2mkv.sh videofile1 --chanid=2033 --starttime=20070704135700 --pass=one video3 --quality=low video4
	videofile1 and chanid=2033/starttime=20070704135700 will be two pass med quality (defaults)
	video3, one pass med quality
	video4, one pass low quality
--maxrunhours=int (default process all files)
	Stop processing files after int hours. (Will complete the current file it is processing.)
--findtitle="string"
	Prints tile, chanid, starttime of programs matching string.
--copydir=directory
	mkv/mp4/avi file will be created in directory. Source nuv will be retained. i.e you are copying the source rather than replacing it.
	If the source was a CHANID/STARTIME it will be renamed to TITLE,S##E##,SUBTITLE. S##E## is the Season and Episode number. All punctuation characters are removed.
	If directory is under MythVideoDir, imdb will be searched, a MythVideo db entry created and a coverfile file created if one was not available at imdb.
--denoise=[ON|OFF] (default OFF)
	Include hqdn3d denoise filter.	
--deblock=[ON|OFF] (default OFF)
	Include pp7 deblock filter.	
--deleterec=[ON|OFF] (default OFF)
	Delete the recording after successful transcode. (Actually just sets high priority autoexpire and moves to Deleted group.)
--crop=[ON|OFF] (default ON)
	Crop 8 pixels of each side.	
--deinterlace==[ON|OFF|SOURCENAME] (default ON)
	Include pp=fd deinterlace filter.
	SOURCENAME is ON for that source. Can have multiple. e.g. DEINTERLACE="Cabel,FTA1"
--invtelecine=[ON|OFF] (default OFF)
	Include pullup inverse telecine filter.
	Note/ This filter will not be added if a deinterlace filter has been added.

Logs to /var/tmp/mythnuv2mkvPID.log and to database if "log MythTV events to database" is enabled in mythtv.
Cutlists are always honored.
Sending the mythnuv2mkv.sh process a USR1 signal will cause it to stop after completing the current file.
e.g. kill -s USR1 PID
If run as a Myth Job, you can find the PID in the System Status Job Queue or Log Entries screens as [PID]

Typical usage.

Myth User Job
PATH/mythnuv2mkv.sh --jobid=%JOBID% --copydir /mythvideodirectory --chanid=%CHANID% --starttime=%STARTTIME%
This will convert nuv to mkv and copy it to /mythvideodirectory.
This is what I do. Record things in Myth Recording and anything I want to keep, use this to convert to mkv and store in Myth Video.
NOTE. System Status Job Queue screen and the Job Queue Comments field in MythWeb always report job Completed Successfully even if it actually failed.

Myth Video
Record program
mythrename.pl --link --format %T-%S --underscores --verbose (mythrename.pl is in the mythtv contrib directory
cp from your mythstore/show_names/PROGRAM to your MythVideo directory
use video manager to add imdb details 
nuv files work fine in MythVideo, but if you need to convert them to mkv/mp4/avi, or need to reduce their size
run mythnuv2mkv.sh MythVideo_file.nuv

Myth Recording
Record program
run mythnuv2mkv.sh --findtitle="title name"
get chanid and starttime
run mythnuv2mkv.sh --chanid=chanid --starttime=starttime
NOTE You cannot edit a avi/mp4/mkv file in Myth Recording. So do all your editing in the nuv file before you convert to avi.
NOTE You cannot play a mkv/mp4 file in Myth Recording.
I would in general recommend leaving everything in Myth Recording as nuv.

Version: $Revision: 1.44 $ $Date: 2009/03/18 20:11:57 $
'
REQUIREDAPPS='
Required Applications
For all contypes
mythtranscode.
perl
mplayer http://www.mplayerhq.hu/design7/news.html
mencoder http://www.mplayerhq.hu/design7/news.html
wget http://www.gnu.org/software/wget/
ImageMagick http://www.imagemagick.org/script/index.php
For avi
mp3lame http://www.mp3dev.org
xvid http://www.xvid.org/
For mkv and mp4 contypes
x264 http://www.videolan.org/developers/x264.html
faac http://sourceforge.net/projects/faac/
faad2 http://sourceforge.net/projects/faac/
For mkv contype
mkvtoolnix http://www.bunkus.org/videotools/mkvtoolnix/
For mkv,ogg contype
vorbis-tools http://www.vorbis.com/
For mp4 contype
MP4Box http://gpac.sourceforge.net/index.php
'
HELP=${USAGE}${REQUIREDAPPS}

##### Mapping #############################################################################################
# Maps tvguide categories to mythvideo ones. This will need to be managed individually.
# Either use the defaults below or create a mythnuv2mkv-category-mappings file in the same
# directory as this and enter data same format as below.
readonly CMAPFILE="$(dirname ${0})/mythnuv2mkv-category-mappings"
if [ -f "$CMAPFILE" ]
then 
	. "$CMAPFILE"
else
	# NOTE: Remove any spaces from XMLTV category. e.g. "Mystery and Suspense" is MysteryandSuspense
	# XMLTV Category		 ; Myth videocategory
	readonly Animated=1		 ; mythcat[1]="Animation"
	readonly Biography=2		 ; mythcat[2]="Documentary"
	readonly Historical=3		 ; mythcat[3]="Documentary"
	readonly CrimeDrama=4		 ; mythcat[4]="CrimeDrama"
	readonly MysteryandSuspense=5	 ; mythcat[5]="Mystery"
	readonly Technology=6		 ; mythcat[6]="Documentary"
	readonly ScienceFiction=7	 ; mythcat[7]="Sci-Fi"
	readonly Science_Fiction=8	 ; mythcat[8]="Sci-Fi"
	readonly art=9			 ; mythcat[9]="Musical"
	readonly History=10		 ; mythcat[10]="Documentary"
	readonly SciFi=11		 ; mythcat[11]="Sci-Fi"
	readonly ScienceNature=12	 ; mythcat[12]="Science"
fi

###########################################################################################################
PATH=~mythtv/bin:${HOME}/bin:$PATH:/usr/local/bin
readonly AVIREQPROGS="mencoder mythtranscode mplayer perl wget convert"
readonly AVIREQLIBS="libmp3lame.so libxvidcore.so"
readonly MP4REQPROGS="mencoder mythtranscode mplayer perl wget convert faac MP4Box"
readonly MP4REQLIBS="libx264.so libfaac.so"
readonly MKVREQPROGS="mencoder mythtranscode mplayer perl wget convert faac oggenc mkvmerge"
readonly MKVREQLIBS="libx264.so libfaac.so"
###########################################################
readonly DENOISEFILTER="hqdn3d"
readonly DEBLOCKFILTER="pp7"
readonly DEINTERLACEFILTER="pp=fd"
readonly INVTELECINEFILTER="pullup"
readonly FAACCHANCONFIG="-I 5,6"
readonly CROPSIZE=8
readonly TE_SCALE43="NA"		# NA
readonly ST_SCALE43="NA"		# NA
readonly FE_SCALE43="640:480"		# 1.32
readonly FS_SCALE43="768:576"		# 1.32
readonly HIGH_SCALE43=528:400		# 1.32
readonly MED_SCALE43=512:384		# 1.333
readonly LOW_SCALE43=448:336		# 1.333
readonly TE_SCALE169="1920:1088" 	# 1.778
readonly ST_SCALE169="1280:720"		# 1.778
readonly FE_SCALE169="848:480" 		# 1.766
readonly FS_SCALE169="1024:576" 	# 1.778
readonly HIGH_SCALE169=656:368		# 1.783
readonly MED_SCALE169=624:352		# 1.773
readonly LOW_SCALE169=592:336		# 1.762
# Default
SCALE43=$MED_SCALE43
SCALE169=$MED_SCALE169
###########################################################
## CQ ## Quote from mencoder documentation
#The CQ depends on the bitrate, the video codec efficiency and the movie resolution. In order to raise the CQ, typically you would
#downscale the movie given that the bitrate is computed in function of the target size and the length of the movie, which are constant.
#With MPEG-4 ASP codecs such as Xvid and libavcodec, a CQ below 0.18 usually results in a pretty blocky picture, because there are
#not enough bits to code the information of each macroblock. (MPEG4, like many other codecs, groups pixels by blocks of several pixels
#to compress the image; if there are not enough bits, the edges of those blocks are visible.) It is therefore wise to take a CQ ranging
# from 0.20 to 0.22 for a 1 CD rip, and 0.26-0.28 for 2 CDs rip with standard encoding options. More advanced encoding options such as
#those listed here for libavcodec and Xvid should make it possible to get the same quality with CQ ranging from 0.18 to 0.20 for a 1 CD
#rip, and 0.24 to 0.26 for a 2 CD rip. With MPEG-4 AVC codecs such as x264, you can use a CQ ranging from 0.14 to 0.16 with standard
#encoding options, and should be able to go as low as 0.10 to 0.12 with x264's advanced encoding settings.
########################
# These map to --quality=low|med|high option.
#### AVI lavc mpeg4 ####
readonly HIGH_LAVC_CQ=0.22
readonly MED_LAVC_CQ=0.21
readonly LOW_LAVC_CQ=0.20
readonly HIGH_LAVC_OPTS="vcodec=mpeg4:threads=${THREADS}:mbd=2:trell:v4mv:last_pred=2:dia=-1:vmax_b_frames=2:vb_strategy=1:cmp=3:subcmp=3:precmp=0:vqcomp=0.6"
# high, med & low will use same settings just CQ and resolution different
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
#readonly MED_LAVC_OPTS="vcodec=mpeg4:mbd=2:trell:v4mv"
#readonly LOW_LAVC_OPTS="vcodec=mpeg4:mbd=2"
readonly MED_LAVC_OPTS="$HIGH_LAVC_OPTS"
readonly LOW_LAVC_OPTS="$HIGH_LAVC_OPTS"
#### AVI xvid mpeg4 ####
readonly HIGH_XVID_CQ=0.22
readonly MED_XVID_CQ=0.21
readonly LOW_XVID_CQ=0.20
readonly HIGH_XVID_OPTS="threads=${THREADS}:quant_type=mpeg:me_quality=6:chroma_me:chroma_opt:trellis:hq_ac:vhq=4:bvhq=1"
readonly MED_XVID_OPTS="$HIGH_XVID_OPTS"
readonly LOW_XVID_OPTS="$HIGH_XVID_OPTS"
#### AVI lavc/xvid mp3 ####
readonly HIGH_MP3_ABITRATE=256
readonly MED_MP3_ABITRATE=192
readonly LOW_MP3_ABITRATE=128
#### MP4/MKV h.263/aac,ogg ####
readonly HIGH_X264_CQ=0.15
readonly MED_X264_CQ=0.14
readonly LOW_X264_CQ=0.13
# H.264 Extended profile (quicktime) level set in QLEVEL
readonly HIGH_X264EXT_OPTS="nocabac:bframes=2:nob_pyramid:threads=auto:direct_pred=auto:subq=6:frameref=5"
# high, med & low will use same settings just CQ and resolution different
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
#readonly MED_X264EXT_OPTS="level_idc=31:nocabac:bframes=2:nob_pyramid:threads=auto:subq=5:frameref=4"
#readonly LOW_X264EXT_OPTS="level_idc=31:nocabac:bframes=2:nob_pyramid:threads=auto:subq=4:frameref=3"
readonly MED_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
readonly LOW_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
# H.264 High profile level set in QLEVEL
readonly HIGH_X264HIGH_OPTS="bframes=3:b_pyramid:weight_b:threads=auto:direct_pred=auto:subq=6:frameref=5:partitions=all:8x8dct:mixed_refs:me=umh:trellis=1"
# high, med & low will use same settings just CQ and resolution different
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
#readonly MED_X264HIGH_OPTS="level_idc=31:bframes=3:b_pyramid:weight_b:threads=auto:subq=5:frameref=4:8x8dct"
#readonly LOW_X264HIGH_OPTS="level_idc=31:bframes=3:b_pyramid:weight_b:threads=auto:subq=4:frameref=3"
readonly MED_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
readonly LOW_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
# AAC
readonly HIGH_AAC_AQUAL=100
readonly MED_AAC_AQUAL=90
readonly LOW_AAC_AQUAL=80
# OGG
readonly HIGH_OGG_AQUAL=6
readonly MED_OGG_AQUAL=5
readonly LOW_OGG_AQUAL=4
# Defaults
LAVC_OPTS=$MED_LAVC_OPTS
LAVC_CQ=$MED_LAVC_CQ
XVID_OPTS=$MED_XVID_OPTS
XVID_CQ=$MED_XVID_CQ
MP3_ABITRATE=$MED_MP3_ABITRATE
AAC_AQUAL=$MED_AAC_AQUAL
OGG_AQUAL=$MED_OGG_AQUAL
X264EXT_OPTS="level_idc=31:$MED_X264EXT_OPTS"
X264_OPTS="level_idc=31:$MED_X264HIGH_OPTS"
X264_CQ=$MED_X264_CQ
if echo "$(basename $0)" | grep -i 'mkv' >/dev/null 2>&1
then
	CONTYPE="mkv"
	QUICKTIME_MP4="NO"
elif echo "$(basename $0)" | grep -i 'mp4' >/dev/null 2>&1
then
	CONTYPE="mp4"
	QUICKTIME_MP4="NO"
elif echo "$(basename $0)" | grep -i 'mov' >/dev/null 2>&1
then
	#TODO. Not working yet don't use mov
	CONTYPE="mp4"
	QUICKTIME_MP4="YES"
elif echo "$(basename $0)" | grep -i 'avi' >/dev/null 2>&1
then
	CONTYPE="avi"
	QUICKTIME_MP4="NO"
fi
###########################################################
# ON or OFF
# debug mode
DEBUG="OFF"
DEBUGSQL="OFF"
DEBUGSG="OFF"
# Print INFO messages
INFO="ON"
# Save(via a rename) or delete nuv file. Only for transcode back into MythRecording.
SAVENUV="OFF"

[ "$DEBUGSQL" = "ON" ] && DEBUG="ON"

##### Functions ###########################################
scriptlog() {
local LEVEL="$1"
shift
local PRIORITY
local HIGHLIGHTON
local HIGHLIGHTOFF
	if [ "$LEVEL" = "BREAK" ]
	then
		echo "--------------------------------------------------------------------------------" | tee -a $LOGFILE
		return 0
	elif [ "$LEVEL" = "ERROR" ]
	then
		PRIORITY=4
		HIGHLIGHTON="${REDFG}"
		HIGHLIGHTOFF="${COLOURORIG}"
		# Global
		FINALEXIT=1
	elif [ "$LEVEL" = "SUCCESS" ]
	then
		PRIORITY=5
		HIGHLIGHTON="${GREENFG}"
		HIGHLIGHTOFF="${COLOURORIG}"
	elif [ "$LEVEL" = "START" -o "$LEVEL" = "STOP" ]
	then
		PRIORITY=5
		HIGHLIGHTON="${BOLDON}"
		HIGHLIGHTOFF="${ALLOFF}"
	elif [ "$LEVEL" = "DEBUG" ]
	then
		[ "$DEBUG" = "ON" ] || return
		PRIORITY=7
		HIGHLIGHTON=""
		HIGHLIGHTOFF=""
	elif [ "$LEVEL" = "NOHEADER" ]
	then
		# Also no db logging
		echo "$*" | tee -a $LOGFILE
		return
	else
		[ "$INFO" = "ON" ] || return
		LEVEL="INFO"
		PRIORITY=6
		HIGHLIGHTON=""
		HIGHLIGHTOFF=""
	fi
	echo "${HIGHLIGHTON}$(date +%d/%m,%H:%M) [${$}] $LEVEL $*${HIGHLIGHTOFF}" | tee -a $LOGFILE

	[ "$DBLOGGING" -eq 1 ] && insertmythlogentry "$PRIORITY" "$LEVEL" "${$}" "$*"
}

chkreqs() {
local REQPROGS="$1"
local REQLIBS="$2"
local TMP
local MENCODER
	for TMP in $REQPROGS
	do
		if ! which "$TMP" >/dev/null 2>&1
		then
			scriptlog ERROR "Can't find program $TMP."
			scriptlog ERROR "$REQUIREDAPPS"
			return 1
		fi
	done
	MENCODER=$(which mencoder)
	for TMP in $REQLIBS
	do
		if ! ldd $MENCODER | grep -i  "${TMP}.*=>.*${TMP}" >/dev/null 2>&1
		then
			scriptlog ERROR "mencoder may not support $TMP."
			scriptlog ERROR "$REQUIREDAPPS"
			return 1
		fi
	done
	return 0
}

versioncheck() {
local PRODUCT="$1"
	case $PRODUCT in
		mkvmerge)
			VER=$(mkvmerge -V | awk '/mkvmerge/ {print $2}')
			OLDIFS="$IFS"; IFS="."; set - $VER; IFS="$OLDIFS"
			MAJ=$(echo "$1" | tr -d [:alpha:]); MIN="$2"; PAT="$3"
			MKVMERGE251BUG="NO"
			if [ "$VER" = "v2.5.1" ]
			then
				scriptlog INFO "mkvmerge v2.5.1. There is a known bug with this version. Workaround applied."
				MKVMERGE251BUG="YES"
			elif [ "$MAJ" -lt 2 -o \( "$MAJ" -eq 2 -a "$MIN" -lt 2 \) ]
			then
				scriptlog INFO "mkvmerge $VER. This will not work with 29.97 fps video (NTSC). You need at least v2.2.0"
			fi
			scriptlog DEBUG "mkvmerge $VER"
		;;
	esac
}

calcbitrate() {
local ASPECT=$1
local SCALE=$2
local CQ=$3
local W
local H
local BITRATE
	W=$(echo $SCALE | cut -d ':' -f1)
	H=$(echo $SCALE | cut -d ':' -f2)
	BITRATE=$(echo "((($H^2 * $ASPECT * 25 * $CQ) / 16 ) * 16) / 1000" | bc)
	echo $BITRATE
}

getsetting() {
local VALUE="$1"
local HOST=$(hostname)
local DATA
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select data from settings where value = "$VALUE" and hostname like "${HOST}%";
	EOF)
	if [ -z "$DATA" ]
	then
		DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		select data from settings where value = "$VALUE" and (hostname is NULL or hostname = "");
	EOF)
	fi
	echo "$DATA"
}

getstoragegroupdirs() {
	mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select distinct dirname from storagegroup;
	EOF
}

hascutlist() {
local CHANID="$1"
local STARTTIME="$2"
local DATA
	[ -n "$CHANID" ] || return 1
	DATA=$(mysql --batch --skip-column-name --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select cutlist from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	[ "$DATA" -eq 1 ] && return 0 || return 1
}

getrecordfile() {
local CHANID="$1"
local STARTTIME="$2"
local DEBUG="$3"
local HOST=$(hostname)
local DATA
local RECFILE
	[ -n "$CHANID" ] || return 1
	# Storage groups
	if [ "$DEBUG" = "ON" ] 
	then
		scriptlog INFO "CHANID $CHANID STARTTIME $STARTTIME HOST $HOST"
		DATA=$(mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		select * from storagegroup;
		select chanid,starttime,title,subtitle,basename,storagegroup from recorded where chanid = $CHANID and starttime = "$STARTTIME";
		EOF)
		scriptlog INFO "Tables"
		scriptlog NOHEADER "$DATA"
	fi
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select concat(a.dirname, "/", b.basename) from storagegroup a, recorded b where b.chanid = $CHANID and b.starttime = "$STARTTIME" and b.storagegroup = a.groupname and a.hostname like "${HOST}%";
	EOF)
	[ "$DEBUG" = "ON" ] && scriptlog INFO "Try 1 Data $DATA"
	while read RECFILE
	do
		[ "$DEBUG" = "ON" ] && scriptlog INFO "Try 1 Check $RECFILE"
		[ -f "${RECFILE}" ] && break
	done < <(echo "$DATA")
	if [ ! -f "$RECFILE" ]
	then
		# Pre Storage groups
		local RFP=$(getsetting RecordFilePrefix)
		DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		select concat("$RFP", "/", basename) from recorded where chanid = $CHANID and starttime = "$STARTTIME" limit 1;
		EOF)
		[ "$DEBUG" = "ON" ] && scriptlog INFO "Try 2 $RFP,$DATA"
		RECFILE="$DATA"
	fi
	[ -f "$RECFILE" ] && echo "$RECFILE"
}

getsourcename() {
local CHANID="$1"
	[ -n "$CHANID" ] || return 1
	mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select b.displayname from channel a, cardinput b where a.chanid = $CHANID and a.sourceid = b.sourceid;
	EOF
}

gettitle() {
local CHANID="$1"
local STARTTIME="$2"
	[ -n "$CHANID" ] || return 1
	mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select title, subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF
}

findchanidstarttime() {
local SEARCHTITLE="$1"
	mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select title, subtitle, chanid, date_format(starttime, '%Y%m%d%H%i%s'), storagegroup from recorded where title like "%${SEARCHTITLE}%";
	EOF
}

updatemetadata() {
local NEW="$1"
local CHANID="$2"
local STARTTIME="$3"
local NFSIZE
	NFSIZE=$(stat -c %s "$NEW")
	NEW=$(basename "$NEW")
	mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	update recorded set
	basename = "$NEW",
	filesize = $NFSIZE,
	bookmark = 0,
	editing = 0,
	cutlist = 0,
	commflagged = 0
	where chanid = $CHANID and starttime = "$STARTTIME";
	delete from recordedmarkup where chanid = $CHANID and starttime = "$STARTTIME";
	delete from recordedseek where chanid = $CHANID and starttime = "$STARTTIME";
	EOF
}

createvideocover() {
local FILENAME="$1"
local ASPECT="$2"
local THDIR="${FIFODIR}/THDIR"
local THUMB_NAME=$(basename "$FILENAME" | sed -e 's/\.[am][vkp][iv4]$/\.png/')
local THUMB_PATH="${CFDIR}/${THUMB_NAME}"
local CURWD
local TH
	{
	CURWD=$(pwd)
	mkdir $THDIR && cd $THDIR || return 1
	nice -19 mplayer -really-quiet -nojoystick -nolirc -nomouseinput -ss 00:02:00 -aspect $ASPECT -ao null -frames 50 -vo png:z=5 "$FILENAME"
	TH=$(ls -1rt | tail -1)
	[ -f "$TH" ] || return
	if [ $ASPECT = "16:9" ]
	then
		convert "$TH" -resize 720x404! THWS.png
	else
		cp "$TH" THWS.png
	fi
	mv THWS.png "$THUMB_PATH"
	cd $CURWD
	rm -rf "$THDIR"
	} >/dev/null 2>&1
	echo "$THUMB_PATH"
}

getsearchtitle() {
local CHANID="$1"
local STARTTIME="$2"
local TI
local ST
local SEARCHTITLE
	[ -n "$CHANID" ] || return 1
	TI=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select title from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	ST=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	if [ -n "$TI" -a -n "$ST" ]
	then
		SEARCHTITLE="${TI}:${ST}"
	elif [ -n "$TI" ]
	then
		SEARCHTITLE="${TI}"
	fi
	echo $SEARCHTITLE
}

lookupinetref() {
# : is used to separate Title and SubTitle in SEARCHTITLE
local SEARCHTITLE="$1"
local CHANID="$2"
local STARTTIME="$3"
local IMDBCMD
local IMDBRES
local IMDBSTR=""
# INETREF will be 00000000 if not found
local INETREF=00000000
local SERIES
local EPISODE
local YEAR
local TMP
	{
        IMDBCMD=$(getsetting MovieListCommandLine)
	# This is dependent on imdb.pl and will not work with any MovieListCommandLine due to use of s=ep option.
	set - $IMDBCMD
	IMDBCMD="$1 $2"
        IMDBRES=$($IMDBCMD "$SEARCHTITLE")
        if [ -n "$IMDBRES" -a $(echo "$IMDBRES" | wc -l) -eq 1 ]
        then
		IMDBSTR="$IMDBRES"
	elif [ -n "$CHANID" ]
	then
		YEAR=$(getyear $CHANID $STARTTIME)
		if [ "$YEAR" -gt 1800 ]
		then
			for C in 0 1 -1
			do
				TMP=$(echo "$IMDBRES" | grep $(( $YEAR + $C )))
				[ -n "$TMP" -a $(echo "$TMP" | wc -l) -eq 1 ] && IMDBSTR="$TMP" && break
			done
		fi
        fi
	if [ -n "$IMDBSTR" ]
	then
                INETREF=$(echo "$IMDBSTR" | awk -F'[^0-9]' '{print $1}')
                echo $INETREF | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*$' >/dev/null 2>&1 || INETREF=00000000
	fi
        if [ "$INETREF" -eq 00000000 ]
        then
		# Try looking for episode
                OLDIFS="$IFS"; IFS=":"; set - $SEARCHTITLE; IFS="$OLDIFS"
		SERIES="$1" ; EPISODE="$2"
		if [ -n "$SERIES" -a -n "$EPISODE" ]
		then
			# option s=ep is for episode lookup
			IMDBSTR=$($IMDBCMD s=ep "$EPISODE")
			if which agrep >/dev/null 2>&1
			then
				IMDBSTR=$(echo "$IMDBSTR" | agrep -i -s -2 "$SERIES" | sort -n | head -1 | cut -d':' -f2-)
			else
				IMDBSTR=$(echo "$IMDBSTR" | grep -i "$SERIES")
			fi
			if [ $(echo "$IMDBSTR" | wc -l) -eq 1 ]
			then
				INETREF=$(echo "$IMDBSTR" | awk -F'[^0-9]' '{print $1}')
				echo $INETREF | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*$' >/dev/null 2>&1 || INETREF=00000000
			fi
		fi
        fi
	scriptlog DEBUG "inetref $INETREF"
	} >/dev/null 2>&1
        echo $INETREF
}

getseriesepisode() {
local CHANID="$1"
local STARTTIME="$2"
local INETREF="$3"
local DATA
local SE
	[ -n "$CHANID" ] || return 1
	{
	# STARTTIME is not always the same in both tables for matching programs. ???
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select syndicatedepisodenumber from recorded a,recordedprogram b
	where a.chanid = $CHANID and a.starttime = "$STARTTIME" and a.chanid = b.chanid
	and a.title = b.title and a.subtitle = b.subtitle;
	EOF)
	DATA=$(echo "$DATA" | awk -F '[SE]' '/S/ {printf("S%02dE%02d\n",$3,$2)}')
	if echo "$DATA" | grep '^S[0-9][0-9]E[0-9][0-9]$' >/dev/null 2>&1
	then
		SE="$DATA"
	elif [ $INETREF -gt 0 ]
	then
		# Lets try passing imdb page
		wget -o /dev/null -O "${FIFODIR}/${INETREF}.html" "http://www.imdb.com/title/tt${INETREF}/"
		SE=$(awk '/Season.*Episode/ {
		a=match($0,/Season ([0-9]+)/,s);b=match($0,/Episode ([0-9]+)/,e);if(a>0 && b>0){printf("S%02dE%02d\n",s[1],e[1]);exit}
		}' "${FIFODIR}/${INETREF}.html")
	fi
	scriptlog DEBUG "series episode $SE"
	} >/dev/null 2>&1
	echo "$SE" | grep '^S[0-9][0-9]E[0-9][0-9]$'
}

createfiletitleSEsubtitle() {
local CHANID="$1"
local STARTTIME="$2"
local SE="$3"
local DATA
local T
local S
	[ -n "$CHANID" ] || return 1
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select title from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	T=$(echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]' | tr '[:space:]' '_')

	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	S=$(echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]' | tr '[:space:]' '_')

	if [ -n "$T" -a -n "$SE" -a -n "$S" ]
	then
		echo "${T}${SEP}${SE}${SEP}${S}"
	elif [ -n "$T" -a -n "$S" ]
	then
		echo "${T}${SEP}${S}"
	else
		echo "${T}"
	fi
}

createvideometadata() {
local FILENAME="$1"
local TITLE="$2"
local ASPECT="$3"
local CHANID="$4"
local STARTTIME="$5"
local INETREF="$6"
# SE may be null
local SE="$7"
local DIRECTOR="Unknown"
#local PLOT="None"
local PLOT="$(getplot $CHANID $STARTTIME)"
local MOVIERATING="NR"
#local YEAR=1895
local YEAR="$(getyear $CHANID $STARTTIME)"
local USERRATING=0
local RUNTIME=0
local COVERFILE="No Cover"
local GENRES=""
local COUNTRIES=""
local CATEGORY=""
local TI
local ST
local IMDBCMD
local IMDBSTR
local GTYPE
local TH
local SE
local S
local E
local WHERE
local INSERT
local TMP
local IDS
local INTID
local COUNT
	# Title name generation is a mess. Should do something better
	if hasvideometadata "$FILENAME"
	then
		scriptlog INFO "$FILENAME already has a videometdata entry"
		return 0
	else
		# Since I strip special characters in TITLE, use chanid/starttime for metadata title.
		if [ -n "$CHANID" ]
		then
			TI=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
			select title from recorded where chanid = $CHANID and starttime = "$STARTTIME";
			EOF)
			ST=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
			select subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
			EOF)
			if [ -n "$TI" -a -n "$SE" -a -n "$ST" ]
			then
				TITLE="\\\"${TI}\\\" ${SE} ${ST}"
			elif [ -n "$TI" -a -n "$ST" ]
			then
				TITLE="\\\"${TI}\\\" ${ST}"
			elif [ -n "$TI" ]
			then
				TITLE="${TI}"
			fi
		fi
		if [ $INETREF -gt 0 ]
		then
			IMDBCMD=$(getsetting MovieDataCommandLine)
			IMDBSTR=$($IMDBCMD $INETREF | sed -e 's/"/\\"/g')
			TMP=$(echo "$IMDBSTR" | grep '^Title' | cut -d':' -f2- | sed -e 's/^ *//')
			if [ -n "$TMP" ]
			then
				# Try and put series and episode number back in. Based on imdb placing quotes around series name. A bit dodgy
				if [ -n "$SE" ]
				then
					TMP=$(echo "$TMP" | awk -v s=${SE} '{
					r=match($0,/"(.*)" (.*)/,m)
					if(r>0) { print("\\\""m[1]"\\\" "s" "m[2]) }
					else { print($0) }
					}' | sed -e 's/\\\\"/\\"/g')
				fi
				TITLE="$TMP"
			fi
			TMP=$(echo "$IMDBSTR" | grep '^Year' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && YEAR="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^Director' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && DIRECTOR="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^Plot' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && PLOT="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^UserRating' | grep -v '[<>\"]' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && USERRATING="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^MovieRating' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && MOVIERATING="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^Runtime' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && RUNTIME="$TMP"
			IMDBCMD=$(getsetting MoviePosterCommandLine)
			IMDBCOVER=$($IMDBCMD $INETREF)
			if [ -n "$IMDBCOVER" ]
			then
				GTYPE=$(echo $IMDBCOVER | sed -e 's/.*\(\....\)/\1/')
				wget -o /dev/null -O ${CFDIR}/${INETREF}${GTYPE} $IMDBCOVER 
				[ -f ${CFDIR}/${INETREF}${GTYPE} ] && COVERFILE="${CFDIR}/${INETREF}${GTYPE}"
			fi
			TMP=$(echo "$IMDBSTR" | grep '^Genres' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && GENRES="$TMP"
			TMP=$(echo "$IMDBSTR" | grep '^Countries' | cut -d':' -f2- | sed -e 's/^ *//')
			[ -n "$TMP" ] && COUNTRIES="$TMP"
		fi
		if ! [ -f "$COVERFILE" ]
		then
			scriptlog INFO "Creating cover file."
			TH=$(createvideocover "$FILENAME" $ASPECT)
			[ -f ${TH} ] && COVERFILE="${TH}"
		fi
		scriptlog INFO "Creating videometadata entry. Inetref:$INETREF. Title:$TITLE"
		if [ "$DEBUGSQL" = "ON" ]
		then
			cat <<-EOF
			insert into videometadata set
			title = "$TITLE",
			director = "$DIRECTOR",
			plot = "$PLOT",
			rating = "$MOVIERATING",
			inetref = "$INETREF",
			year = $YEAR,
			userrating = $USERRATING,
			length = $RUNTIME,
			showlevel = 1,
			filename = "$FILENAME",
			coverfile = "$COVERFILE",
			childid = -1,
			browse = 1,
			playcommand = NULL,
			category = 0;
			EOF
		fi
		mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		insert into videometadata set
		title = "$TITLE",
		director = "$DIRECTOR",
		plot = "$PLOT",
		rating = "$MOVIERATING",
		inetref = "$INETREF",
		year = $YEAR,
		userrating = $USERRATING,
		length = $RUNTIME,
		showlevel = 1,
		filename = "$FILENAME",
		coverfile = "$COVERFILE",
		childid = -1,
		browse = 1,
		playcommand = NULL,
		category = 0;
		EOF
		CATEGORY=$(getcategory "$CHANID" "$STARTTIME")
		if [ -n "$GENRES" -o -n "$COUNTRIES" -o -n "$CATEGORY" ]
		then
			INTID=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
			select intid from videometadata where filename = "$FILENAME";
			EOF)
		fi
		if [ -n "$INTID" ]
		then
			# This will not create new genres, countries or categories.
			if [ -n "$GENRES" ]
			then
				scriptlog DEBUG "Will check for genres $GENRES"
				OLDIFS="$IFS"; IFS=','; set - $GENRES; IFS="$OLDIFS"
				COUNT="$#"
				WHERE=""
				for TMP in "$@"
				do
					TMP=$(echo $TMP | tr [A-Z] [a-z])
					[ -n "$WHERE" ] && WHERE="$WHERE or lcase(genre) = \"$TMP\"" || WHERE="where lcase(genre) = \"$TMP\""
				done
				[ "$DEBUGSQL" = "ON" ] && echo "select intid from videogenre $WHERE"
				IDS=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
				select intid from videogenre $WHERE; 
				EOF)
				for TMP in $IDS
				do
					INSERT="$INSERT insert into videometadatagenre set idvideo = $INTID, idgenre = $TMP;"
				done
				[ "$COUNT" -gt $(echo "$IDS" | wc -l) ] && scriptlog INFO "Not all genres $GENRES found"
			fi

			if [ -n "$COUNTRIES" ]
			then
				scriptlog DEBUG "Will check for countries $COUNTRIES"
				OLDIFS="$IFS"; IFS=','; set - $COUNTRIES; IFS="$OLDIFS"
				COUNT="$#"
				WHERE=""
				for TMP in "$@"
				do
					TMP=$(echo $TMP | tr [A-Z] [a-z])
					[ -n "$WHERE" ] && WHERE="$WHERE or lcase(country) = \"$TMP\"" || WHERE="where lcase(country) = \"$TMP\""
				done
				[ "$DEBUGSQL" = "ON" ] && echo "select intid from videocountry $WHERE"
				IDS=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
				select intid from videocountry $WHERE; 
				EOF)
				for TMP in $IDS
				do
					INSERT="$INSERT insert into videometadatacountry set idvideo = $INTID, idcountry = $TMP;"
				done
				[ "$COUNT" -gt $(echo "$IDS" | wc -l) ] && scriptlog INFO "Not all countries $COUNTRIES found"
			fi

			if [ -n "$CATEGORY" ]
			then
				CATEGORY=$(echo "$CATEGORY" | tr -d ' ')
				OLDIFS="$IFS"; IFS='/'; set - $CATEGORY; IFS="$OLDIFS"
				for TMP in "$@"
				do
					# Use mappings
					[ -n "${mythcat[$TMP]}" ] && TMP=${mythcat[$TMP]}
					[ "$DEBUGSQL" = "ON" ] && echo "select intid from videocategory where lcase(category) = lcase("$TMP")"
					IDS=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} mythconverg <<-EOF
					select intid from videocategory where lcase(category) = lcase("$TMP"); 
					EOF)
					if [ -n "$IDS" ]
					then
						INSERT="$INSERT update videometadata set category = $IDS where intid = $INTID;"
						scriptlog INFO "Added to category $TMP"
						# only 1 category
						break
					else
						scriptlog INFO "Category $TMP does not exist"
					fi
				done
			fi

			if [ -n "$INSERT" ]
			then
				[ "$DEBUGSQL" = "ON" ] && echo "$INSERT"
				mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} mythconverg <<-EOF
				$INSERT
				EOF
			fi
		fi
	fi
	return 0
}

hasvideometadata() {
local FILENAME="$1"
local DATA
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select intid from videometadata where filename = "$FILENAME";
	EOF)
	echo $DATA | grep '^[0-9][0-9][0-9]*$' >/dev/null 2>&1 && return 0 || return 1
}

deleterecording() {
local CHANID="$1"
local STARTTIME="$2"
	[ -n "$CHANID" ] || return 1
	mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	update recorded set recgroup = "Deleted", autoexpire = 999 where chanid = $CHANID and starttime = "$STARTTIME";
	EOF
}

insertmythlogentry() {
local PRIORITY="$1"
local LEVEL="$2"
local PID="$3"
local DETAILS="$(echo $4 | tr -d '[:cntrl:]' | tr -d '[\\\"]')"
local DATETIME=$(date '+%Y%m%d%H%M%S')
local HOST=$(hostname)
	mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	insert into mythlog set
	module = "mythnuv2mkv.sh",
	priority = $PRIORITY,
	acknowledged = 0,
	logdate = $DATETIME,
	host = "$HOST",
	message = "mythnuv2mkv.sh [$PID] $LEVEL",
	details = "$DETAILS";
	EOF
}

getjobqueuecmds() {
local JOBID="$1"
local DATA
local JQCMDSTR[0]="RUN"
local JQCMDSTR[1]="PAUSE"
local JQCMDSTR[2]="RESUME"
local JQCMDSTR[4]="STOP"
local JQCMDSTR[8]="RESTART"
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select cmds from jobqueue where id = $JOBID;
	EOF)
	echo ${JQCMDSTR[$DATA]}
}

setjobqueuecmds() {
local JOBID="$1"
local CMDSSTR="$2"
local CMDS
	if echo "$CMDSSTR" | egrep '^[0-9]+$' >/dev/null 2>&1
	then
		CMDS=$CMDSSTR
	elif [ "$CMDSSTR" = "RUN" ]
	then
		CMDS=0
	fi
	if [ -n "$CMDS" ]
	then
		mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		update jobqueue set cmds = $CMDS where id = $JOBID;
		EOF
	else
		scriptlog ERROR "Invalid Job Queue Command."
	fi
}

getjobqueuestatus() {
local JOBID="$1"
local DATA
local JQSTATUSSTR[0]="UNKNOWN"
local JQSTATUSSTR[1]="QUEUED"
local JQSTATUSSTR[2]="PENDING"
local JQSTATUSSTR[3]="STARTING"
local JQSTATUSSTR[4]="RUNNING"
local JQSTATUSSTR[5]="STOPPING"
local JQSTATUSSTR[6]="PAUSED"
local JQSTATUSSTR[7]="RETRY"
local JQSTATUSSTR[8]="ERRORING"
local JQSTATUSSTR[9]="ABORTING"
local JQSTATUSSTR[256]="DONE"
local JQSTATUSSTR[272]="FINISHED"
local JQSTATUSSTR[288]="ABORTED"
local JQSTATUSSTR[304]="ERRORED"
local JQSTATUSSTR[320]="CANCELLED"
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select status from jobqueue where id = $JOBID;
	EOF)
	echo ${JQSTATUSSTR[$DATA]}
}

setjobqueuestatus() {
local JOBID="$1"
local STATUSSTR="$2"
local STATUS
	if echo "$STATUSSTR" | egrep '^[0-9]+$' >/dev/null 2>&1
	then
		STATUS=$STATUSSTR
	elif [ "$STATUSSTR" = "RUNNING" ]
	then
		STATUS=4
	elif [ "$STATUSSTR" = "PAUSED" ]
	then
		STATUS=6
	elif [ "$STATUSSTR" = "ABORTING" ]
	then
		STATUS=9
	elif [ "$STATUSSTR" = "FINISHED" ]
	then
		STATUS=272
	elif [ "$STATUSSTR" = "ERRORED" ]
	then
		STATUS=304
	fi
	if [ -n "$STATUS" ]
	then
		mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
		update jobqueue set status = $STATUS where id = $JOBID;
		EOF
	else
		scriptlog ERROR "Invalid Job Queue Status."
	fi
}

getjobqueuecomment() {
local JOBID="$1"
local COMMENT="$2"
	mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select comment from jobqueue where id = $JOBID;
	EOF
}

setjobqueuecomment() {
local JOBID="$1"
local COMMENT="$2"
	mysql --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	update jobqueue set comment = "$COMMENT" where id = $JOBID;
	EOF
}

# My channelprofiles table for setting aspect at channel level.
# See http://web.aanet.com.au/auric/?q=node/1
# You probably don't have it.
getchannelaspect() {
local CHANID=$1
local DATA
	{
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} ${DBName} <<-EOF
	select aspectratio from channelprofiles
		where channum = (select channum from channel where chanid = $CHANID)
		and sourceid = (select sourceid from channel where chanid = $CHANID);
	EOF)
	case $DATA in
		16:9|4:3) true ;;
		'') DATA=$DEFAULTMPEG2ASPECT ;;
		*) DATA=NA ;;
	esac
	} >/dev/null 2>&1
	echo $DATA
}

# aspect ratio of the V4L or MPEG capture card associated with CHANID
# No good for any other type of card. e.g. DVB.
querycardaspect() {
local CHANID=$1
local DATA
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} ${DBName} <<-EOF
	select value from codecparams where name = 'mpeg2aspectratio'
	and profile = (select id from recordingprofiles where name = 'default'
		and profilegroup = (select id from profilegroups
			where cardtype = (select cardtype from capturecard
				where cardid = (select cardid from cardinput
					where sourceid = (select sourceid from channel
						where chanid = $CHANID)
					)
				)
			)
		);
	EOF)
	[ "$DATA" != "4:3" -a "$DATA" != "16:9" ] && DATA="NA"
	echo $DATA
}

getaviinfo() {
local FILE="$1"
shift
local PROPS="$@"
local MPOP
local TMP
local p
local RES
local ASPECTFOUNDIN
readonly width=1		; infokey[1]="ID_VIDEO_WIDTH"
readonly height=2		; infokey[2]="ID_VIDEO_HEIGHT"
readonly fps=3			; infokey[3]="ID_VIDEO_FPS"
readonly audio_sample_rate=4	; infokey[4]="ID_AUDIO_RATE"
readonly audio_channels=5	; infokey[5]="ID_AUDIO_NCH"
readonly aspect=6		; infokey[6]="ID_VIDEO_ASPECT"
	MPOP=$(mplayer -really-quiet -nojoystick -nolirc -nomouseinput -vo null -ao null -frames 0 -identify "$FILE" 2>/dev/null)
	for p in $PROPS
	do
		[ -n "${infokey[$p]}" ] && p=${infokey[$p]}
		case $p in
			"finfo")
				TMP="NA"
			;;
			"ID_VIDEO_ASPECT")
				TMP="$(echo "$MPOP" | awk -F'=' '/ID_VIDEO_ASPECT/ {if($2>1.1 && $2<1.5)print "4:3";if($2>1.6 && $2<2)print "16:9"}')"
				[ "$TMP" != "4:3" -a "$TMP" != "16:9" ] && TMP="NA"
				ASPECTFOUNDIN="File"
				if [ "$TMP" = "NA" ] && echo "$FILE" | grep '\.mpg$' >/dev/null 2>&1 && [ -n "$CHANID" ]
				then
					TMP=$(getchannelaspect $CHANID)
					ASPECTFOUNDIN="Channel"
				fi
				if [ "$TMP" = "NA" ] && echo "$FILE" | grep '\.mpg$' >/dev/null 2>&1 && [ -n "$CHANID" ]
				then
					TMP=$(querycardaspect $CHANID)
					ASPECTFOUNDIN="Card"
				fi
				if [ "$TMP" = "NA" ] && echo "$FILE" | grep '\.mpg$' >/dev/null 2>&1
				then
					TMP=$DEFAULTMPEG2ASPECT
					ASPECTFOUNDIN="Default"
				fi
				TMP="$TMP,$ASPECTFOUNDIN"
			;;
			"ID_VIDEO_HEIGHT")
				TMP="$(echo "$MPOP" | grep $p | tail -1 | cut -d'=' -f2)"
				[ "$TMP" = "1080" ] && TMP="1088" # HD FIX
			;;
			*)
				TMP="$(echo "$MPOP" | grep $p | tail -1 | cut -d'=' -f2)"
			;;
		esac
		[ -z "$RES" ] && RES="$TMP" || RES="${RES}:${TMP}"
	done
	echo "$RES"
}

getnuvinfo() {
export NUVINFOFILE="$1"
shift
export NUVINFOPROPS="$@"
	PROPS=$(sed -n '/^#STARTNUVINFO$/,/#ENDNUVINFO/p' $CMD | perl)
	echo "$PROPS"
}

getvidinfo() {
local FILE="$1"
shift
local PROPS="$@"
local RES
	if echo "$FILE" | grep '\.nuv' >/dev/null 2>&1
	then	
		RES=$(getnuvinfo "$FILE" $PROPS)
	else
		RES=$(getaviinfo "$FILE" $PROPS)
	fi
	echo "$RES"
}

getaspect() {
local FILE="$1"
local ASPECT="NA"
	ASPECT=$(getvidinfo "$FILE" aspect)
	echo "$ASPECT" | grep ',' >/dev/null 2>&1 || ASPECT="$ASPECT,File"
	echo "$ASPECT"
}

stoptime() {
local STARTSECS=$1
local MAXRUNHOURS=$2
local CURSECS
local ENDSECS
	[ "$MAXRUNHOURS" = "NA" ] && return 1
	CURSECS=$(date +%s)
	ENDSECS=$(( $STARTSECS + ( $MAXRUNHOURS * 60 * 60 ) ))
	[ "$ENDSECS" -gt "$CURSECS" ] && return 1 || return 0
}

checkoutput() {
local INPUT="$1"
local OUTPUT="$2"
local MENCODERRES=$3
local VIDFOR
local OUTSIZE
local INSIZE
local RAT
local SCANOUTFILE
local LCOUNT
local ECOUNT
local INFRAMES
local OUTFRAMES
local DIFF
	VIDFOR=$(getvidinfo "$OUTPUT" ID_VIDEO_FORMAT)
	if [ "$VIDFOR" != "FMP4" -a "$VIDFOR" != "h264" -a "$VIDFOR" != "avc1" -a "$VIDFOR" != "avc1" -a "$VIDFOR" != "XVID" ]
	then
		scriptlog ERROR "$OUTPUT does not look like correct avi/mp4/mkv file."
		return 1
	fi

	OUTSIZE=$(stat -c %s "$OUTPUT" 2>/dev/null || echo 0)
	if [ "$OUTSIZE" -eq 0 ]
	then
		scriptlog ERROR "$OUTPUT zero length."
		return 1
	fi

	INSIZE=$(stat -c %s "$INPUT" 2>/dev/null || echo 0)
	RAT=$(( $INSIZE / $OUTSIZE ))
	if ! hascutlist $CHANID $STARTTIME && [ "$RAT" -gt 16 ]
	then
		scriptlog ERROR "ratio between $INPUT and $OUTPUT sizes greater than 16."
		return 1
	fi

	SCANOUTFILE="${FIFODIR}/mplayerscan-out"
	nice mplayer -benchmark -nojoystick -nolirc -nomouseinput -vo null -ao null -speed 10 "$OUTPUT" 2>&1 | tr '\r' '\n' >$SCANOUTFILE 2>&1
	LCOUNT=$(wc -l $SCANOUTFILE 2>/dev/null | awk '{T=$1} END {if(T>0){print T}else{print 0}}')
	if [ "$LCOUNT" -lt 1000 ]
	then
		scriptlog ERROR "mplayer line count ($LCOUNT) to low on $OUTPUT."
		return 1
	fi
	ECOUNT=$(egrep -ic 'sync|error|skip|damaged|overflow' $SCANOUTFILE)
	if [ "$ECOUNT" -gt 5 ]
	then
		scriptlog ERROR "mplayer error count ($ECOUNT) to great on $OUTPUT."
		return 1
	fi

	# Latest mplayer does not output frame count
	#if [ -f "$MENCODERRES" ]
	#then
	#	OUTFRAMES=$(tail -40 $SCANOUTFILE | awk '/A-V:/ {if(match($5,"/"))F=$5;if(match($6,"/"))F=$6;if(match($7,"/"))F=$7;if(match($8,"/"))F=$8;if(match($9,"/"))F=$9} END {print substr(F,index(F,"/")+1)}')
	#	INFRAMES=$(tail -40 $MENCODERRES | awk '/Video stream:/ {F=$12} END {print F}')
	#	scriptlog INFO "Frames $INFRAMES $INPUT."
	#	scriptlog INFO "Frames $OUTFRAMES $OUTPUT."
	#	if echo ${INFRAMES} : ${OUTFRAMES} | grep '[0-9] : [0-9]' >/dev/null 2>&1
	#	then
	#		DIFF=$([ $INFRAMES -gt $OUTFRAMES ] && echo $(( $INFRAMES - $OUTFRAMES )) || echo $(( $OUTFRAMES - $INFRAMES )))
	#	else
	#		DIFF=100000
	#	fi
	#	if [ "$DIFF" -gt 10 ]
	#	then
	#		scriptlog ERROR "Frame count difference of $DIFF to big on $OUTPUT."
	#		return 1
	#	fi
	#fi

	return 0
}

getcategory() {
local CHANID="$1"
local STARTTIME="$2"
local DATA
	[ -n "$CHANID" ] || return 1
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select category from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]'
}

getplot() {
local CHANID="$1"
local STARTTIME="$2"
local DATA
	[ -n "$CHANID" ] || return 1
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select description from recorded where chanid = $CHANID and starttime = "$STARTTIME";
	EOF)
	echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]'
}

getyear() {
local CHANID="$1"
local STARTTIME="$2"
local DATA
	[ -n "$CHANID" ] || return 1
	# STARTTIME is not always the same in both tables for matching programs. ???
	DATA=$(mysql --batch --skip-column-names --user=${DBUserName} --password=${DBPassword} -h ${DBHostName} ${DBName} <<-EOF
	select airdate from recorded a,recordedprogram b
	where a.chanid = $CHANID and a.starttime = "$STARTTIME" and a.chanid = b.chanid
	and a.title = b.title and a.subtitle = b.subtitle;
	EOF)
	[ -n "$DATA" -a $DATA -gt 1800 ] && echo $DATA || echo $(date +%Y)
}

encloseincontainer() {
local OUTBASE="$1"
local FPS="$2"
local AUDEXT="$3"
local CONTYPE="$4"
local ASPECT="$5"
local TITLE="$6"
	if [ -f "${OUTBASE}_video.h264" -o "${OUTBASE}_audio.${AUDEXT}" ]
	then
		if [ "$CONTYPE" = "mkv" ]
		then
			if [ "$MKVMERGE251BUG" = "YES" ]
			then
				LANG=C mkvmerge --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$TITLE" \
				"${OUTBASE}_video.h264" "${OUTBASE}_audio.${AUDEXT}" -o "${OUTBASE}.mkv"
				RET=$? ; [ $RET -eq 1 ] && RET=0 # mkvmerge return code of 1 is only a warning
			else
				mkvmerge --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$TITLE" \
				"${OUTBASE}_video.h264" "${OUTBASE}_audio.${AUDEXT}" -o "${OUTBASE}.mkv"
				RET=$? ; [ $RET -eq 1 ] && RET=0 # mkvmerge return code of 1 is only a warning
			fi
		elif [ "$CONTYPE" = "mp4" ]
		then
			MP4Box -add "${OUTBASE}_video.h264:par=1:1" -add "${OUTBASE}_audio.${AUDEXT}" -fps $FPS "${OUTBASE}.mp4"
			RET=$?
		fi
		if [ $RET -eq 0 ]
		then
			[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}_video.h264" "${OUTBASE}_audio.${AUDEXT}"
		else
			[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}_video.h264" "${OUTBASE}_audio.${AUDEXT}" "${OUTBASE}.mkv" >/dev/null 2>&1
			return 1
		fi
	else
		scriptlog ERROR "${OUTBASE}_video.h264 or ${OUTBASE}_audio.${AUDEXT} does not exist."
		return 1
	fi
	return 0
}

logtranstime () {
local START=$1
local END=$2
local ORIGINALFILESIZE=$3
local NEWFILESIZE=$4
	TMP=$(( $(date -u -d"${END}" +%s) - $(date -u -d"${START}" +%s) ))
	DAYS=$(( $TMP / 60 / 60 / 24 ))
	HOURS=$(( $TMP / 60 / 60 - ($DAYS * 24) ))
	MINUTES=$(( $TMP / 60 - ( ($HOURS * 60)+($DAYS * 24 * 60) ) ))
	SECONDS=$(( $TMP - ( ($MINUTES * 60)+($HOURS * 60 * 60)+($DAYS * 24 * 60 * 60) ) ))
	scriptlog INFO "RUNTIME: $DAYS days $HOURS hours $MINUTES minutes and $SECONDS seconds. Original filesize: $ORIGINALFILESIZE New filesize: $NEWFILESIZE"
}

cleanup() {
local SIG="$1"
local JOBID="$2"
local OUTPUT="$3"
local OUTBASE
local TRANPID
	scriptlog DEBUG "$SIG Clean up."
	if [ "$SIG" = "ABRT" ]
	then
		scriptlog ERROR "Job Aborted. Removing incomplete $OUTPUT."
		OUTBASE=$(echo "$OUTPUT" | sed -e 's/\.[ma][pv][4i]$//')
		[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}.avi" "${OUTBASE}_video.h264" "${OUTBASE}_audio.aac" "${OUTBASE}_audio.ogg" "${OUTBASE}.mp4" "${OUTBASE}.mkv" >/dev/null 2>&1
	fi

	TRANPID=$(jobs -l | awk '/mythtranscode/ {P=$2" "P} END {print P}')
	if [ -n "$TRANPID" ]
	then
		scriptlog DEBUG "Killing mythtranscode [$TRANPID]"
		ps -p $TRANPID >/dev/null 2>&1 && kill $TRANPID >/dev/null 2>&1
	fi

	if [ "$FINALEXIT" -eq 0 ]
	then
		[ "$DEBUG" != "ON" ] && rm -rf "$FIFODIR" >/dev/null 2>&1
		scriptlog INFO "Exiting. Successful."
		if [ "$JOBID" -ne 99999999 ]
		then
			setjobqueuestatus "$JOBID" "FINISHED"
			setjobqueuecomment "$JOBID" "[${$}] Successfully Completed"
		fi
		exit 0
	else
		scriptlog INFO "Exiting. Errored."
		if [ "$JOBID" -ne 99999999 ]
		then
			setjobqueuestatus "$JOBID" "ERRORED"
			setjobqueuecomment "$JOBID" "[${$}] Errored"
		fi
		#exit 1
		#exit 304
		# Only error code jobqueue.cpp interprets is 246. This is translated to "unable to find executable".
		scriptlog ERROR "This error could be for many reasons. Mythtv will report unable to find executable, this is incorrect."
		exit 246
	fi
}

MYSQLLIST="~mythtv/.mythtv/mysql.txt ~/.mythtv/mysql.txt /.mythtv/mysql.txt /usr/local/share/mythtv/mysql.txt /usr/share/mythtv/mysql.txt /etc/mythtv/mysql.txt /usr/local/etc/mythtv/mysql.txt mysql.txt"
for m in $MYSQLLIST
do
	[ -f $m ] && . $m && break
done
if [ -z "$DBName" ]
then
	echo "Can't find mysql.txt"
	exit 1
fi

##### BG Monitor #####################################
# This will be fired off in background to update the jobqueue comment and process stop/pause/resume requests.
if echo "$1" | egrep -i '\-\-monitor=' >/dev/null 2>&1
then
	readonly MONJOBID=$(echo "$1" | cut -d'=' -f2)
	readonly MONPID="$2"
	readonly MONTRANSOP="$3"
	readonly LOGFILE="$4"
	readonly DBLOGGING=$(getsetting "LogEnabled")

	[ "$MONJOBID" -ne 99999999 -a -n "$MONPID" ] || exit 1

	PAUSEALREADYPRINTED="" ; RESUMEALREADYPRINTED=""
	
	scriptlog INFO "Starting monitoring process."
	sleep 5
	while ps -p $MONPID >/dev/null 2>&1
	do
		JQCMD=$(getjobqueuecmds "$MONJOBID")
		if [ "$JQCMD" = "PAUSE" ]
		then
			JQSTATUS=$(getjobqueuestatus "$MONJOBID")
			if [ "$JQSTATUS" != "PAUSED" ]
			then
				MENCODERPID=$(ps --ppid $MONPID | awk '/mencoder/ {print $1}')
				if [ -n "$MENCODERPID" ]
				then
					PAUSEALREADYPRINTED=""
					STARTPAUSESECS=$(date +%s)
					kill -s STOP $MENCODERPID
					setjobqueuestatus "$MONJOBID" "PAUSED"
					SAVEDCC=$(getjobqueuecomment "$MONJOBID")
					setjobqueuecomment "$MONJOBID" "[$MONPID] Paused for 0 Seconds"
					scriptlog STOP "Job Paused due to job queue pause request."
				else
					[ -z "$PAUSEALREADYPRINTED" ] && scriptlog ERROR "Sorry, could not pause. Will keep trying"
					PAUSEALREADYPRINTED=TRUE
				fi
			else
				NOW=$(date +%s)
				PAUSESECS=$(( $NOW - $STARTPAUSESECS ))
				PAUSEMINS=$(( $PAUSESECS / 60 ))
				PAUSEHOURS=$(( $PAUSEMINS / 60 ))
				PAUSEMINS=$(( $PAUSEMINS - ( $PAUSEHOURS * 60 ) ))
				PAUSESECS=$(( $PAUSESECS - ( ( $PAUSEHOURS * 60 * 60 ) + ( $PAUSEMINS * 60 ) ) ))
				setjobqueuecomment "$MONJOBID" "[$MONPID] Paused for $PAUSEHOURS Hrs $PAUSEMINS Mins $PAUSESECS Secs"
			fi
		elif [ "$JQCMD" = "RESUME" ]
		then
			JQSTATUS=$(getjobqueuestatus "$MONJOBID")
			if [ "$JQSTATUS" != "RUNNING" ]
			then
				MENCODERPID=$(ps --ppid $MONPID | awk '/mencoder/ {print $1}')
				if [ -n "$MENCODERPID" ]
				then
					RESUMEALREADYPRINTED=""
					kill -s CONT $MENCODERPID
					setjobqueuestatus "$MONJOBID" "RUNNING"
					setjobqueuecomment "$MONJOBID" "$SAVEDCC"
					scriptlog START "Job resumed due to job queue resume request."
					setjobqueuecmds "$MONJOBID" "RUN"
				else
					[ -z "$RESUMEALREADYPRINTED" ] && scriptlog ERROR "Sorry, could not resume. Will keep trying"
					RESUMEALREADYPRINTED=TRUE
				fi
			fi
		elif [ "$JQCMD" = "STOP" ]
		then
			setjobqueuestatus "$MONJOBID" "ABORTING"
			setjobqueuecomment "$MONJOBID" "[$MONPID] Stopping"
			scriptlog STOP "Stopping due to job queue stop request."
			setjobqueuecmds "$MONJOBID" "RUN"
			kill -s ABRT $MONPID
			sleep 2
			kill $MONPID
		elif [ "$JQCMD" = "RESTART" ]
		then
			scriptlog ERROR "Sorry, can't restart job."
			setjobqueuecmds "$MONJOBID" "RUN"
		else
			CC=$(getjobqueuecomment "$MONJOBID")
			if echo "$CC" | grep 'audio pass' >/dev/null 2>&1
			then
				PASSNU="audio pass"
			elif echo "$CC" | grep 'Single video pass' >/dev/null 2>&1
			then
				PASSNU="Single video pass"
			elif echo "$CC" | grep '1st video pass' >/dev/null 2>&1
			then
				PASSNU="1st video pass"
			elif echo "$CC" | grep '2nd video pass' >/dev/null 2>&1
			then
				PASSNU="2nd video pass"
			else
				sleep 15
				continue
			fi
			PCTLINE=$(tail -10 $MONTRANSOP | grep 'mythtranscode:' | cut -c39- | tail -1)
			[ -n "$PASSNU" -a -n "$PCTLINE" ] && setjobqueuecomment "$MONJOBID" "[$MONPID] $PASSNU $PCTLINE"
		fi
		sleep 15
	done
	exit
fi

##### Globals ########################################
readonly CMD="$0"
readonly LOGFILE="/var/tmp/mythnuv2mkv${$}.log"
readonly FIFODIR="/var/tmp/mythnuv2mkv${$}"
readonly MENCODEROP="${FIFODIR}/mencoder.op"
readonly TRANSOP="${FIFODIR}/transcode.op"
readonly STOPREQUEST="${FIFODIR}/STOPREQUEST"
readonly CFDIR=$(getsetting "VideoArtworkDir")
if ! tty >/dev/null 2>&1
then
	readonly BOLDON=""
	readonly ALLOFF=""
	readonly REDFG=""
	readonly GREENFG=""
	readonly COLOURORIG=""
	[ "$DEBUG" = "ON" ] && exec 3>/var/tmp/DEBUG || exec 3>/dev/null
	exec 1>&3
	exec 2>&3
else
	readonly BOLDON=`tput bold`
	readonly ALLOFF=`tput sgr0`
	readonly REDFG=`tput setaf 1`
	readonly GREENFG=`tput setaf 2`
	readonly COLOURORIG=`tput op`
fi
# DBLOGGING is reverse to shell true/false
DBLOGGING=0
OUTPUT=""
JOBID=99999999
FINALEXIT=0
STARTSECS="NA"
MAXRUNHOURS="NA"

##### Main ###########################################
if echo "$1" | egrep -i '\-help|\-usage|\-\?' >/dev/null 2>&1
then
	echo "$HELP"
	exit 1
fi

if [ "$CONTYPE" = "mkv" ]
then
	chkreqs "$MKVREQPROGS" "$MKVREQLIBS" || exit 1
	versioncheck "mkvmerge"
elif [ "$CONTYPE" = "mp4" ]
then
	chkreqs "$MP4REQPROGS" "$MP4REQLIBS" || exit 1
elif [ "$CONTYPE" = "avi" ]
then
	chkreqs "$AVIREQPROGS" "$AVIREQLIBS" || exit 1
fi

trap 'cleanup ABRT "$JOBID" "$OUTPUT"' INT ABRT
trap 'touch $STOPREQUEST ; scriptlog INFO "USR1 received. Will stop after current file completes."' USR1
trap 'cleanup EXIT "$JOBID"' EXIT
mkdir ${FIFODIR} >/dev/null 2>&1

for INPUT in "$@"
do
	if stoptime $STARTSECS $MAXRUNHOURS
	then
		scriptlog STOP "Stopping due to max runtime $MAXRUNHOURS."
		scriptlog BREAK 
		break
	fi
	if [ -f "$STOPREQUEST" ]
	then
		scriptlog STOP "Stopping due to USR1 request."
		scriptlog BREAK 
		break
	fi

	# Jobid from myth user job %JOBID%
	if echo "$INPUT" | grep -i '\-\-jobid=' >/dev/null 2>&1
	then
		JOBID=$(echo "$INPUT" | cut -d'=' -f2)
		DBLOGGING=$(getsetting "LogEnabled")
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-findtitle=' >/dev/null 2>&1
	then
		SEARCHTITLE=$(echo "$INPUT" | cut -d'=' -f2)
		MATCHTITLE=$(findchanidstarttime "$SEARCHTITLE")	
		echo "$MATCHTITLE"
		exit 0
	fi

	if echo "$INPUT" | grep -i '\-\-maxrunhours=' >/dev/null 2>&1
	then
		STARTSECS=$(date +%s)
		MAXRUNHOURS=$(echo "$INPUT" | cut -d'=' -f2)
		scriptlog INFO "Max Run Hours set to $MAXRUNHOURS."
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-debugsg' >/dev/null 2>&1
	then
		DEBUGSG="ON"
		scriptlog INFO "DEBUGSG set ON."
		continue
	fi
	if echo "$INPUT" | grep -i '\-\-debug=' >/dev/null 2>&1
	then
		DEBUG=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		scriptlog INFO "Debug set to $DEBUG."
		continue
	fi
	if echo "$INPUT" | grep -i '\-\-info=' >/dev/null 2>&1
	then
		INFO=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		scriptlog INFO "Info set to $INFO."
		continue
	fi
	if echo "$INPUT" | grep -i '\-\-savenuv=' >/dev/null 2>&1
	then
		SAVENUV=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		scriptlog INFO "SaveNUV set to $SAVENUV."
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-denoise=' >/dev/null 2>&1
	then
		DENOISE=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		if echo "$DENOISE" | egrep -i 'ON|YES' >/dev/null 2>&1
		then
			POSTVIDFILTERS="${POSTVIDFILTERS}${DENOISEFILTER},"
			scriptlog INFO "Denoise filter added."
		else
			POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'${DENOISEFILTER}',//')
			scriptlog INFO "Denoise filter removed."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-deblock=' >/dev/null 2>&1
	then
		DEBLOCK=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		if echo "$DEBLOCK" | egrep -i 'ON|YES' >/dev/null 2>&1
		then
			POSTVIDFILTERS="${POSTVIDFILTERS}${DEBLOCKFILTER},"
			scriptlog INFO "Deblock filter added."
		else
			POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'${DEBLOCKFILTER}',//')
			scriptlog INFO "Deblock filter removed."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-deinterlace=' >/dev/null 2>&1
	then
		DEINTERLACE=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		if echo "$DEINTERLACE" | egrep -i 'ON|YES' >/dev/null 2>&1
		then
			scriptlog INFO "Deinterlace filter made available."
		else
			scriptlog INFO "Deinterlace filter made unavailable."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-invtelecine=' >/dev/null 2>&1
	then
		INVTELECINE=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		if echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1
		then
			scriptlog INFO "Invtelecine filter made available."
		else
			scriptlog INFO "Invtelecine filter made unavailable."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-crop=' >/dev/null 2>&1
	then
		CROP=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		scriptlog INFO "Crop set to $CROP."
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-deleterec=' >/dev/null 2>&1
	then
		DELETEREC=$(echo "$INPUT" | cut -d'=' -f2 | tr [a-z] [A-Z])
		scriptlog INFO "Delete Recording set to $DELETEREC."
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-copydir=' >/dev/null 2>&1
	then
		COPYDIR=$(echo "$INPUT" | cut -d'=' -f2)
		if [ -d "$COPYDIR" -a -w "$COPYDIR" ]
		then
			scriptlog INFO "Video will be located in $COPYDIR."
		else
			scriptlog ERROR "$COPYDIR does not exist or is not writable. Continuing but result will be left in source directory unless $COPYDIR is created before job completes."
		fi	
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-contype=' >/dev/null 2>&1
	then
		TMP=$(echo "$INPUT" | cut -d'=' -f2 | tr [A-Z] [a-z])
		OLDIFS="$IFS"; IFS=","; set - $TMP; IFS="$OLDIFS"
		TMP1="$1" ; TMP2="$2"
		if [ "$TMP1" = "mp4" ]
		then
			if [ -n "$CHANID" -a -z "$COPYDIR" ]
			then
				scriptlog ERROR "Changed to $TMP1 failed. mp4 not supported in MythRecord."
			elif ! chkreqs "$MP4REQPROGS" "$MP4REQLIBS"
			then
				scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
			else
				CONTYPE="mp4"
				QUICKTIME_MP4="NO"
				scriptlog INFO "Changed to $CONTYPE."
			fi
		elif [ "$TMP1" = "mov" ]
		then
			if [ -n "$CHANID" -a -z "$COPYDIR" ]
			then
				scriptlog ERROR "Changed to $TMP1 failed. mov not supported in MythRecord."
			elif ! chkreqs "$MP4REQPROGS" "$MP4REQLIBS"
			then
				scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
			else
				CONTYPE="mp4"
				QUICKTIME_MP4="YES"
				scriptlog INFO "Changed to $CONTYPE (mov)."
			fi
		elif [ "$TMP1" = "mkv" ]
		then
			if [ -n "$CHANID" -a -z "$COPYDIR" ]
			then
				scriptlog ERROR "Changed to $TMP1 failed. mkv not supported in MythRecord."
			elif ! chkreqs "$MKVREQPROGS" "$MKVREQLIBS"
			then
				scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
			else
				CONTYPE="mkv"
				QUICKTIME_MP4="NO"
				[ "$TMP2" = "ogg" ] && MKVAUD="ogg"
				[ "$TMP2" = "acc" ] && MKVAUD="acc"
				scriptlog INFO "Changed to ${CONTYPE},${MKVAUD}."
			fi
		elif [ "$TMP1" = "avi" ]
		then
			if ! chkreqs "$AVIREQPROGS" "$AVIREQLIBS"
			then
				scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
			else
				CONTYPE="avi"
				QUICKTIME_MP4="NO"
				[ "$TMP2" = "xvid" ] && AVIVID="xvid"
				[ "$TMP2" = "lavc" ] && AVIVID="lavc"
				[ "$TMP2" = "divx" ] && AVIVID="lavc"
				scriptlog INFO "Changed to ${CONTYPE},${AVIVID}."
			fi
		else
			scriptlog ERROR "Changed to $TMP1 failed. Invalid contype."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-pass=' >/dev/null 2>&1
	then
		TMP=$(echo "$INPUT" | cut -d'=' -f2 | tr [A-Z] [a-z])
		if [ "$TMP" = "one" -o "$TMP" = "1" ]
		then
			scriptlog INFO "Changed to $TMP pass."
			PASS="one"
		elif [ "$TMP" = "two" -o "$TMP" = "2" ]
		then
			scriptlog INFO "Changed to $TMP pass."
			PASS="two"
		else
			scriptlog ERROR "Changed to $TMP failed. Invalid contype."
		fi
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-quality=' >/dev/null 2>&1
	then
		QLEVEL=$(echo "$INPUT" | cut -d'=' -f2)
		if echo "$QLEVEL" | grep -i "high" >/dev/null 2>&1
		then
			SCALE43=$HIGH_SCALE43
			SCALE169=$HIGH_SCALE169
			LAVC_CQ=$HIGH_LAVC_CQ
			LAVC_OPTS=$HIGH_LAVC_OPTS
			XVID_CQ=$HIGH_XVID_CQ
			XVID_OPTS=$HIGH_XVID_OPTS
			MP3_ABITRATE=$HIGH_MP3_ABITRATE
			X264_CQ=$HIGH_X264_CQ
			X264EXT_OPTS="level_idc=31:$HIGH_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$HIGH_X264HIGH_OPTS"
			AAC_AQUAL=$HIGH_AAC_AQUAL
			OGG_AQUAL=$HIGH_OGG_AQUAL
		elif echo "$QLEVEL" | grep -i "med" >/dev/null 2>&1
		then
			SCALE43=$MED_SCALE43
			SCALE169=$MED_SCALE169
			LAVC_CQ=$MED_LAVC_CQ
			LAVC_OPTS=$MED_LAVC_OPTS
			XVID_CQ=$MED_XVID_CQ
			XVID_OPTS=$MED_XVID_OPTS
			MP3_ABITRATE=$MED_MP3_ABITRATE
			X264_CQ=$MED_X264_CQ
			X264EXT_OPTS="level_idc=31:$MED_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$MED_X264HIGH_OPTS"
			AAC_AQUAL=$MED_AAC_AQUAL
			OGG_AQUAL=$MED_OGG_AQUAL
		elif echo "$QLEVEL" | grep -i "low" >/dev/null 2>&1
		then
			SCALE43=$LOW_SCALE43
			SCALE169=$LOW_SCALE169
			LAVC_CQ=$LOW_LAVC_CQ
			LAVC_OPTS=$LOW_LAVC_OPTS
			XVID_CQ=$LOW_XVID_CQ
			XVID_OPTS=$LOW_XVID_OPTS
			MP3_ABITRATE=$LOW_MP3_ABITRATE
			X264_CQ=$LOW_X264_CQ
			X264EXT_OPTS="level_idc=31:$LOW_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$LOW_X264HIGH_OPTS"
			AAC_AQUAL=$LOW_AAC_AQUAL
			OGG_AQUAL=$LOW_OGG_AQUAL
		elif echo "$QLEVEL" | egrep -i "480" >/dev/null 2>&1
		then
			# 720 scale, high everything else
			SCALE43=$FE_SCALE43
			SCALE169=$FE_SCALE169
			LAVC_CQ=$HIGH_LAVC_CQ
			LAVC_OPTS=$HIGH_LAVC_OPTS
			XVID_CQ=$HIGH_XVID_CQ
			XVID_OPTS=$HIGH_XVID_OPTS
			MP3_ABITRATE=$HIGH_MP3_ABITRATE
			X264_CQ=$HIGH_X264_CQ
			X264EXT_OPTS="level_idc=31:$HIGH_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$HIGH_X264HIGH_OPTS"
			AAC_AQUAL=$HIGH_AAC_AQUAL
			OGG_AQUAL=$HIGH_OGG_AQUAL
		elif echo "$QLEVEL" | egrep -i "576" >/dev/null 2>&1
		then
			# 720 scale, high everything else
			SCALE43=$FS_SCALE43
			SCALE169=$FS_SCALE169
			LAVC_CQ=$HIGH_LAVC_CQ
			LAVC_OPTS=$HIGH_LAVC_OPTS
			XVID_CQ=$HIGH_XVID_CQ
			XVID_OPTS=$HIGH_XVID_OPTS
			MP3_ABITRATE=$HIGH_MP3_ABITRATE
			X264_CQ=$HIGH_X264_CQ
			X264EXT_OPTS="level_idc=31:$HIGH_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$HIGH_X264HIGH_OPTS"
			AAC_AQUAL=$HIGH_AAC_AQUAL
			OGG_AQUAL=$HIGH_OGG_AQUAL
		elif echo "$QLEVEL" | egrep -i "720" >/dev/null 2>&1
		then
			# 720 scale, high everything else
			SCALE43=$ST_SCALE43
			SCALE169=$ST_SCALE169
			LAVC_CQ=$HIGH_LAVC_CQ
			LAVC_OPTS=$HIGH_LAVC_OPTS
			XVID_CQ=$HIGH_XVID_CQ
			XVID_OPTS=$HIGH_XVID_OPTS
			MP3_ABITRATE=$HIGH_MP3_ABITRATE
			X264_CQ=$HIGH_X264_CQ
			X264EXT_OPTS="level_idc=31:$HIGH_X264EXT_OPTS"
			X264_OPTS="level_idc=31:$HIGH_X264HIGH_OPTS"
			AAC_AQUAL=$HIGH_AAC_AQUAL
			OGG_AQUAL=$HIGH_OGG_AQUAL
		elif echo "$QLEVEL" | grep -i "1080" >/dev/null 2>&1
		then
			# 1080 scale, high everything else
			SCALE43=$TE_SCALE43
			SCALE169=$TE_SCALE169
			LAVC_CQ=$HIGH_LAVC_CQ
			LAVC_OPTS=$HIGH_LAVC_OPTS
			XVID_CQ=$HIGH_XVID_CQ
			XVID_OPTS=$HIGH_XVID_OPTS
			MP3_ABITRATE=$HIGH_MP3_ABITRATE
			X264_CQ=$HIGH_X264_CQ
			X264EXT_OPTS="level_idc=41:$HIGH_X264EXT_OPTS"
			X264_OPTS="level_idc=41:$HIGH_X264HIGH_OPTS"
			AAC_AQUAL=$HIGH_AAC_AQUAL
			OGG_AQUAL=$HIGH_OGG_AQUAL
		fi
		scriptlog INFO "Changed to $QLEVEL quality."
		continue
	fi

	if echo "$INPUT" | grep -i '\-\-chanid=' >/dev/null 2>&1
	then
		CHANID=$(echo "$INPUT" | cut -d'=' -f2)
		continue
	fi
	if echo "$INPUT" | grep -i '\-\-starttime=' >/dev/null 2>&1
	then
		STARTTIME=$(echo "$INPUT" | cut -d'=' -f2)
		if [ -z "$CHANID" ]
		then
			scriptlog ERROR "Skipping $STARTTIME. chanid not specified."
			scriptlog ERROR "--chanid must be specified before --starttime."
			scriptlog BREAK 
			unset STARTTIME
			continue
		fi
		if [ "$DEBUGSG" = "ON" ]
		then
			INPUT=$(getrecordfile "$CHANID" "$STARTTIME" "$DEBUGSG")
			scriptlog INFO "$INPUT" 
			scriptlog BREAK 
			exit $FINALEXIT
		fi
		INPUT=$(getrecordfile "$CHANID" "$STARTTIME")
		if [ -z "$INPUT" ]
		then
			scriptlog ERROR "Skipping $CHANID $STARTTIME. Did not match a recording."
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
		if [ ! -f "$INPUT" ]
		then
			scriptlog ERROR "Could not find Recording. ($INPUT)"
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
		TITLE=$(gettitle $CHANID $STARTTIME)
		MTINFILE=""
		MTSOURCE="--chanid $CHANID --starttime $STARTTIME"
		hascutlist $CHANID $STARTTIME && MTSOURCE="--honorcutlist $MTSOURCE"
		scriptlog INFO "$CHANID $STARTTIME matches $TITLE ($INPUT)"
	else
		echo "$INPUT" | grep '^\/' >/dev/null 2>&1 || INPUT="`pwd`/${INPUT}"
		MTINFILE="--infile"
		MTSOURCE="$INPUT"
	fi

	if [ ! -f "$INPUT" ]
	then
		scriptlog ERROR "Skipping $INPUT does not exist."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	if echo "$INPUT" | grep -v '\.[nm][up][vg]$' >/dev/null 2>&1
	then
		scriptlog ERROR "Skipping $INPUT not a nuv or mpg file."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	OUTBASE=$(echo "$INPUT" | sed -e 's/\.[nm][up][vg]$//')
	OUTPUT="${OUTBASE}.${CONTYPE}"
	if [ -f "$OUTPUT" ]
	then
		scriptlog ERROR "Skipping $INPUT. $OUTPUT already exists."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	INSIZE=$(( `stat -c %s "${INPUT}"` / 1024 ))
	FREESPACE=$(df -k "$INPUT" | awk 'END {print $3}')
	if [ $(( $FREESPACE - $INSIZE )) -lt 10000 ]
	then
		scriptlog ERROR "Stopping due to disk space shortage."
		scriptlog BREAK 
		break
	fi

	[ "$QUICKTIME_MP4" = "YES" ] && X264_OPTS="$X264EXT_OPTS"

	FILEINFO=$(getvidinfo "$INPUT" width height fps audio_sample_rate audio_channels)
	OLDIFS="$IFS"; IFS=":"; set - $FILEINFO; IFS="$OLDIFS"
	INWIDTH="$1"; INHEIGHT="$2"; INFPS="$3"; INARATE="$4"; CHANNELS="$5"
	if [ "$#" -ne 5 ]
	then
		scriptlog ERROR "Skipping $INPUT. Could not obtain vid format details"
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi
	if [ "$INWIDTH" = 720 -a "$INHEIGHT" = 576 ]
	then
		FORMAT="576i or 576p"
	elif [ "$INWIDTH" = 720 -a "$INHEIGHT" = 480 ]
	then
		FORMAT="480i or 480p"
	elif [ "$INWIDTH" = 1280 -a "$INHEIGHT" = 720 ]
	then
		FORMAT="720p"
	elif [ "$INWIDTH" = 1920 -a "$INHEIGHT" = 1088 ]
	then
		FORMAT="1080i or 1080p"
	else
		FORMAT="Unknown"
	fi

	ASPECTSTR="NA";ASPECTFOUNDIN="NA"
	TMP=$(getaspect "$INPUT")
	ASPECTSTR=$(echo "$TMP" | cut -d',' -f1)
	ASPECTFOUNDIN=$(echo "$TMP" | cut -d',' -f2)
	if [ "$ASPECTSTR" != "4:3" -a "$ASPECTSTR" != "16:9" ]
	then
		scriptlog ERROR "Skipping $INPUT. Aspect is $ASPECTSTR must be 16:9 or 4:3."
		scriptlog ERROR "If this is a mpg file make sure to set DEFAULTMPEG2ASPECT at top of this script."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi
	scriptlog INFO "$FORMAT ${INWIDTH}x${INHEIGHT} $ASPECTSTR (Found in $ASPECTFOUNDIN) $INFPS FPS Audio Rate $INARATE Channels $CHANNELS"

	# Channel mapping
	FAACCCOPT=""
	case "$CHANNELS" in
		1*|2*|3*|4*) true ;;
		5*|6*) FAACCCOPT="$FAACCHANCONFIG" ;;
		*) scriptlog ERROR "Audio channels $CHANNELS invalid."
		   scriptlog BREAK 
		   unset CHANID STARTTIME
		   continue
		;;
	esac

	# Aspect/Scale/Crop opts
	if [ "$ASPECTSTR" = "4:3" ]
	then
		ASPECT=1.333333333
		SCALE=$SCALE43
		if [ "$SCALE" = "NA" ]
		then
			scriptlog ERROR "Skipping $INPUT Aspect 4:3 which is not supported for quality $QLEVEL"
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
	elif [ "$ASPECTSTR" = "16:9" ]
	then
		ASPECT=1.77777777778
		SCALE=$SCALE169
	fi
	SCALESTR=$( echo $SCALE | tr ':' 'x' )
	SCALEMEN="scale=${SCALE},"

	OLDIFS="$IFS"; IFS=":"; set - $SCALE; IFS="$OLDIFS"
	OUTWIDTH="$1"; OUTHEIGHT="$2"
	if [ "$OUTWIDTH" = "$INWIDTH" -a "$OUTHEIGHT" = "$INHEIGHT" ]
	then
		CROPSCALE=""
		scriptlog INFO "Input and Output same resolution. crop,scale disabled."
	elif echo "$CROP" | egrep -i 'ON|YES' >/dev/null 2>&1
	then
		if [ "$OUTWIDTH" -gt "$INWIDTH" -o "$OUTHEIGHT" -gt "$INHEIGHT" ]
		then
			scriptlog INFO "Output is a greater scale than input. This is not sensible."
		fi
		CROPX=$CROPSIZE
		CROPY=$CROPSIZE
		CROPW=$(( $INWIDTH - ( 2 * $CROPX ) ))
		CROPH=$(( $INHEIGHT - ( 2 * $CROPY ) ))
		CROPVAL="${CROPW}:${CROPH}:${CROPX}:${CROPY}"
		CROPMEN="crop=${CROPVAL},"
		CROPSCALE="${CROPMEN}${SCALEMEN}"
		scriptlog INFO "Crop to $CROPVAL. Scale to $SCALESTR."
	else
		CROPSCALE="${SCALEMEN}"
		scriptlog INFO "Scale to $SCALESTR."
	fi

	# Filter opts
	OUTFPS="$INFPS" ; MENOUTFPS=""
	POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'"${INVTELECINEFILTER}"',//')
	POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'"${DEINTERLACEFILTER}"',//')
	[ -n "$CHANID" ] && SOURCENAME=$(getsourcename $CHANID)
	# Progressive then skip Deinterlace/Invtelecine
	if echo $INFPS | egrep '^23|^24' >/dev/null 2>&1
	then
		# Keep 23.976 FPS otherwise mencoder will convert to 29.97
		OUTFPS="23.976"
		scriptlog INFO "Input $INFPS FPS. OUTFPS set to $OUTFPS."
	elif [ "$FORMAT" = "720p" -o "$FORMAT" = "1080p" ]
	then
		scriptlog INFO "$FORMAT. Deinterlace/Invtelecine filter not needed."
	# Deinterlace options
	elif echo "$DEINTERLACE" | egrep -i 'ON|YES' >/dev/null 2>&1
	then
		POSTVIDFILTERS="${POSTVIDFILTERS}${DEINTERLACEFILTER},"
		scriptlog INFO "Deinterlace filter added."
		echo "$INFPS" | grep  '^29' >/dev/null 2>&1 &&
			scriptlog INFO "You may need Invtelecine rather than Deinterlace. (--deinterlace=NO --invtelecine=YES)."
		echo "$FORMAT" | egrep -i '576p|480p|720p|1080p' >/dev/null 2>&1 &&
			scriptlog INFO "If progressive this is wrong use --deinterlace=NO."
	elif [ -n "$SOURCENAME" ] && echo "$DEINTERLACE" | grep -i "$SOURCENAME" >/dev/null 2>&1
	then
		POSTVIDFILTERS="${POSTVIDFILTERS}${DEINTERLACEFILTER},"
		scriptlog INFO "Source $SOURCENAME. Deinterlace filter added."
		echo "$INFPS" | grep  '^29' >/dev/null 2>&1 &&
			scriptlog INFO "You may need Invtelecine rather than Deinterlace. (--deinterlace=NO --invtelecine=YES)."
		echo "$FORMAT" | egrep -i '576p|480p|720p|1080p' >/dev/null 2>&1 &&
			scriptlog INFO "If progressive this is wrong use --deinterlace=NO."
	# Invtelecine options
	elif echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1 && echo $INFPS | egrep '^24|^25' >/dev/null 2>&1
	then
		# Very unusual to have PAL/DVB telecine video
		scriptlog INFO "Input $INFPS FPS. Invtelecine filter not supported."
	elif echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1
	then
		POSTVIDFILTERS="${POSTVIDFILTERS}${INVTELECINEFILTER},"
		OUTFPS="23.976"
		scriptlog INFO "Invtelecine filter added."
	fi
	[ "$OUTFPS" = "23.976" ] && MENOUTFPS="-ofps 24000/1001"
	[ -n "$POSTVIDFILTERS" ] && POSTVIDFILTERS="${POSTVIDFILTERS}softskip,"

	# Encoder opts
	# Force avi for videos staying in MythRecord
	if [ "$CONTYPE" = "avi" ] || [ -n "$CHANID" -a -z "$COPYDIR" ]
	then
		if [ "$AVIVID" = "xvid" ]
		then
			VBITRATE=$(calcbitrate $ASPECT $SCALE $XVID_CQ)
			PASSCMD="pass"
			VIDEOCODEC="-ovc xvid -xvidencopts ${XVID_OPTS}:bitrate=${VBITRATE}"
			VIDEXT="xvid"
		elif [ "$AVIVID" = "lavc" ]
		then
			VBITRATE=$(calcbitrate $ASPECT $SCALE $LAVC_CQ)
			PASSCMD="vpass"
			VIDEOCODEC="-ovc lavc -lavcopts ${LAVC_OPTS}:vbitrate=${VBITRATE}"
			VIDEXT="lavc"
		else
			scriptlog ERROR "Skipping $INPUT. Unsupported avi encoder"
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
		ABITRATE=$MP3_ABITRATE
		AUDIOCODEC="-oac mp3lame -lameopts vbr=2:br=${ABITRATE}"
		AUDEXT="mp3"
		MENOUT1STPASS="-aspect $ASPECT -force-avi-aspect $ASPECTSTR -o /dev/null"
		MENOUTOPT="-aspect $ASPECT -force-avi-aspect $ASPECTSTR -o"
		MENOUTFILE="$OUTPUT"
	elif [ "$CONTYPE" = "mp4" ]
	then
		VBITRATE=$(calcbitrate $ASPECT $SCALE $X264_CQ)
		AQUAL=$AAC_AQUAL
		PASSCMD="pass"
		VIDEOCODEC="-ovc x264 -x264encopts ${X264_OPTS}:bitrate=${VBITRATE}"
		VIDEXT="h264"
		AUDIOCODEC="-oac copy"
		AUDEXT="aac"
		MENOUT1STPASS="-of rawvideo -o /dev/null"
		MENOUTOPT="-of rawvideo -o"
		MENOUTFILE="${OUTBASE}_video.h264"
	elif [ "$CONTYPE" = "mkv" ]
	then
		VBITRATE=$(calcbitrate $ASPECT $SCALE $X264_CQ)
		if [ "$MKVAUD" = "ogg" ]
		then
			AQUAL=$OGG_AQUAL
			AUDEXT="ogg"
		elif [ "$MKVAUD" = "aac" ]
		then
			AQUAL=$AAC_AQUAL
			AUDEXT="aac"
		else
			scriptlog ERROR "Skipping $INPUT. Unsupported mkv encoder"
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
		PASSCMD="pass"
		VIDEOCODEC="-ovc x264 -x264encopts ${X264_OPTS}:bitrate=${VBITRATE}"
		VIDEXT="h264"
		AUDIOCODEC="-oac copy"
		MENOUT1STPASS="-of rawvideo -o /dev/null"
		MENOUTOPT="-of rawvideo -o"
		MENOUTFILE="${OUTBASE}_video.h264"
	else
		scriptlog ERROR "Skipping $INPUT. Incorrect video contype selected. $CONTYPE"
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	MENOPTS="${VIDEOCODEC} \
	${AUDIOCODEC} \
	-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS"
	scriptlog INFO "MENCODEROPTS: $MENOPTS."

	RETCODE=0
	# Fireoff a background monitoring job to update the job queue details
	[ "$JOBID" -ne 99999999 ] && $CMD --monitor=$JOBID ${$} $TRANSOP $LOGFILE &

	#Start time
	ENCSTARTTIME=$(date +%Y-%m-%d\ %H:%M:%S)
	ORIGINALFILESIZE=$(du -h "$INPUT" | cut -f1)

	# mp4/mkv have seperate Audio/Video transcodes.
	if [ "$AUDEXT" = "aac" ]
	then
		scriptlog START "Starting $AUDEXT audio trans of $INPUT. quality $AQUAL."
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] audio pass started"

		if [ ! -f "${OUTBASE}_audio.${AUDEXT}" ]
		then
			rm -f ${FIFODIR}/*out $TRANSOP $MENCODEROP
			if [ -n "$MTINFILE" ]
			then
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir $FIFODIR | tee -a $TRANSOP &
			else
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir $FIFODIR | tee -a $TRANSOP &
			fi
			sleep 10
			# Throw away video
			nice -n 19 dd bs=512k if=${FIFODIR}/vidout of=/dev/null &
			nice -n 19 faac ${FIFODIR}/audout -P -R $INARATE -C $CHANNELS $FAACCCOPT -X -q $AQUAL --mpeg-vers 4 -o "${OUTBASE}_audio.${AUDEXT}"
			RETCODE=$?
			sleep 10
			if [ $RETCODE -ne 0 ]
			then
				scriptlog ERROR "Skipping $INPUT. Problem with audio pass."
				scriptlog BREAK 
				unset CHANID STARTTIME
				continue
			fi
		fi
	elif [ "$AUDEXT" = "ogg" ]
	then
		scriptlog START "Starting $AUDEXT audio trans of $INPUT. quality $AQUAL."
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] audio pass started"

		if [ ! -f "${OUTBASE}_audio.${AUDEXT}" ]
		then
			rm -f ${FIFODIR}/*out $TRANSOP $MENCODEROP
			if [ -n "$MTINFILE" ]
			then
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir $FIFODIR | tee -a $TRANSOP &
			else
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir $FIFODIR | tee -a $TRANSOP &
			fi
			sleep 10
			# Throw away video
			nice -n 19 dd bs=512k if=${FIFODIR}/vidout of=/dev/null &
			nice -n 19 oggenc --raw-chan=${CHANNELS} --raw-rate=${INARATE} --quality=${AQUAL} -o "${OUTBASE}_audio.${AUDEXT}" ${FIFODIR}/audout
			RETCODE=$?
			sleep 10
			if [ $RETCODE -ne 0 ]
			then
				scriptlog ERROR "Skipping $INPUT. Problem with audio pass."
				scriptlog BREAK 
				unset CHANID STARTTIME
				continue
			fi
		fi
	fi

	if [ "$PASS" = "one" ]
	then
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Single video pass started."
		scriptlog START "Starting $VIDEXT Single video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
		if [ ! -f "$MENOUTFILE" ]
		then
			rm -f ${FIFODIR}/*out $TRANSOP $MENCODEROP
			if [ -n "$MTINFILE" ]
			then
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir $FIFODIR | tee -a $TRANSOP &
			else
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir $FIFODIR | tee -a $TRANSOP &
			fi
			sleep 10
			nice -n 19 mencoder -idx -noskip \
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
			${VIDEOCODEC} \
			${AUDIOCODEC} \
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
			$MENOUTOPT "$MENOUTFILE" | tee -a $MENCODEROP
			RETCODE=$?
			sleep 10
		fi
	else
		scriptlog START "Starting $VIDEXT 1st video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] 1st video pass started."
		if [ ! -f "$MENOUTFILE" ]
		then
			rm -f ${FIFODIR}/*out $TRANSOP $MENCODEROP
			if [ -n "$MTINFILE" ]
			then
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir $FIFODIR | tee -a $TRANSOP &
			else
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir $FIFODIR | tee -a $TRANSOP &
			fi
			sleep 10
			nice -n 19 mencoder -idx \
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
			${VIDEOCODEC}:${PASSCMD}=1:turbo -passlogfile ${FIFODIR}/2pass.log \
			${AUDIOCODEC} \
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
			$MENOUT1STPASS
			RETCODE=$?
			sleep 10
			if [ $RETCODE -ne 0 ]
			then
				scriptlog ERROR "Skipping $INPUT. Problem with 1st video pass of 2."
				scriptlog BREAK 
				unset CHANID STARTTIME
				continue
			fi
		fi

		scriptlog START "Starting $VIDEXT 2nd video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] 2nd video pass started."
		if [ ! -f "$MENOUTFILE" ]
		then
			rm -f ${FIFODIR}/*out $TRANSOP $MENCODEROP
			if [ -n "$MTINFILE" ]
			then
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir $FIFODIR | tee -a $TRANSOP &
			else
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir $FIFODIR | tee -a $TRANSOP &
			fi
			sleep 10
			nice -n 19 mencoder -idx -noskip \
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
			${VIDEOCODEC}:${PASSCMD}=2 -passlogfile ${FIFODIR}/2pass.log \
			${AUDIOCODEC} \
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
			$MENOUTOPT "$MENOUTFILE" | tee -a $MENCODEROP
			RETCODE=$?
			sleep 10
		fi
	fi

	if [ $RETCODE -ne 0 ]
	then
		scriptlog ERROR "Skipping $INPUT. Problem with final video pass. $OUTPUT may exist."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	if [ -n "$CHANID" ]
	then
		SEARCHTITLE=$(getsearchtitle "$CHANID" "$STARTTIME")
		INETREF=$(lookupinetref "$SEARCHTITLE" "$CHANID" "$STARTTIME")
		SERIESEPISODE=$(getseriesepisode "$CHANID" "$STARTTIME" "$INETREF")
		TITLE=$(createfiletitleSEsubtitle "$CHANID" "$STARTTIME" "$SERIESEPISODE")
	else
		TITLE=$(basename "$OUTPUT" | sed -e 's/\.[am][vkp][iv4]$//')
	fi

	if [ "$CONTYPE" = "mp4" -o "$CONTYPE" = "mkv" ]
	then
		scriptlog START "Joining ${OUTBASE}_video.h264 ${OUTBASE}_audio.${AUDEXT} in $CONTYPE container."
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Joining in $CONTYPE container."
		if ! encloseincontainer "$OUTBASE" $OUTFPS $AUDEXT $CONTYPE $ASPECTSTR $TITLE
		then
			scriptlog ERROR "$CONTYPE container Failed for $OUTPUT."
			scriptlog BREAK 
			unset CHANID STARTTIME
			continue
		fi
	fi

	scriptlog START "Checking $OUTPUT."
	[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Checking result."
	if ! checkoutput "$INPUT" "$OUTPUT" "$MENCODEROP"
	then
		mv "$OUTPUT" "${OUTPUT}-SUSPECT"
		scriptlog ERROR "$OUTPUT may be faulty. Saved as ${OUTPUT}-SUSPECT. $INPUT kept."
		scriptlog BREAK 
		unset CHANID STARTTIME
		continue
	fi

	if [ -n "$COPYDIR" ]
	then
		# Is this a good idea?
		#CATEGORY=$(getcategory "$CHANID" "$STARTTIME")
		#[ -n "$CATEGORY" ]
		#then
		#	COPYDIR="${COPYDIR}/${CATEGORY}"
		#fi
		[ -d "$COPYDIR" ] || mkdir -p "$COPYDIR"
		COPYFILE="${TITLE}.${CONTYPE}"
		while [ -f "${COPYDIR}/${COPYFILE}" ]
		do
			COUNT=$(( ${COUNT:=0} + 1 ))
			COPYFILE="${TITLE}_${COUNT}.${CONTYPE}"
		done
		if cp "$OUTPUT" "${COPYDIR}/${COPYFILE}"
		then
			rm -f "$OUTPUT"
			scriptlog SUCCESS "Successful trans. $INPUT trans to ${COPYDIR}/${COPYFILE}. $INPUT kept"
			MYTHVIDDIR=$(getsetting VideoStartupDir)
			if [ "$QUICKTIME_MP4" = "YES" ]
			then
				OLDFILE="${COPYDIR}/${COPYFILE}"
				COPYFILE=$(echo "$COPYFILE" | sed -e 's/mp4$/mov/')
				mv "$OLDFILE" "${COPYDIR}/${COPYFILE}"
			fi
			if echo "$COPYDIR" | grep "$MYTHVIDDIR" >/dev/null 2>&1
			then
				createvideometadata "${COPYDIR}/${COPYFILE}" "$TITLE" "$ASPECTSTR" "$CHANID" "$STARTTIME" "$INETREF" "$SERIESEPISODE"
			fi
			if echo "$DELETEREC" | egrep -i 'ON|YES' >/dev/null 2>&1
			then
				scriptlog INFO "Deleting recording."
				deleterecording "$CHANID" "$STARTTIME"
			fi
			NEWFILESIZE=$(du -h "${COPYDIR}/${COPYFILE}" | cut -f1)
		else
			scriptlog ERROR "Successful trans but copy to ${COPYDIR}/${COPYFILE} bad. $INPUT trans to $OUTPUT. $INPUT kept"
		fi
	else
		if [ -n "$CHANID" ]
		then
			scriptlog INFO "Updating MythRecord db to $OUTPUT."
			updatemetadata "$OUTPUT" "$CHANID" "$STARTTIME"
			# mythcommflag --rebuild does not work correctly for avi files.
			# Without this you can't edit files, but with it seeks don't work correctly.
			#scriptlog INFO "Rebuilding seektable for $OUTPUT."
			#mythcommflag --chanid "$CHANID" --starttime "$STARTTIME" --rebuild >/dev/null
			rm -f "${INPUT}.png"
		fi
		[ "$DEBUG" = "ON" -o "$SAVENUV" = "ON" ] && mv "$INPUT" "${INPUT}OK-DONE"
		[ "$DEBUG" != "ON" -a "$SAVENUV" != "ON" ] && rm -f "$INPUT"
		scriptlog SUCCESS "Successful trans to $OUTPUT. $INPUT removed."
		NEWFILESIZE=$(du -h "$OUTPUT" | cut -f1)
	fi
	# End time
	ENCENDTIME=$(date +%Y-%m-%d\ %H:%M:%S)
	logtranstime "$ENCSTARTTIME" "$ENCENDTIME" "$ORIGINALFILESIZE" "$NEWFILESIZE"
	scriptlog BREAK 
	unset CHANID STARTTIME
done
exit $FINALEXIT


#STARTNUVINFO
#!/usr/bin/perl
# $Date: 2009/03/18 20:11:57 $
# $Revision: 1.44 $
# $Author: mythtv $
#
#  mythtv::nuvinfo.pm
#
#   exports one routine:  nuv_info($path_to_nuv)
#   This routine inspects a specified nuv file, and returns information about
#   it, gathered either from its nuv file structure
#
# Auric grabbed from nuvexport and Modified. Thanks to the nuvexport guys, I never would have been able to work this out
#
# finfo version width height desiredheight desiredwidth pimode aspect fps videoblocks audioblocks textsblocks keyframedist video_type audio_type audio_sample_rate audio_bits_per_sample audio_channels audio_compression_ratio audio_quality rtjpeg_quality rtjpeg_luma_filter rtjpeg_chroma_filter lavc_bitrate lavc_qmin lavc_qmax lavc_maxqdiff seektable_offset keyframeadjust_offset

# Byte swap a 32-bit number from little-endian to big-endian
    sub byteswap32 {
       # Read in a 4-character string
       my $in = shift;
       my $out = $in;

       if ($Config{'byteorder'} == 4321) {
           substr($out, 0, 1) = substr($in, 3, 1);
           substr($out, 3, 1) = substr($in, 0, 1);
           substr($out, 1, 1) = substr($in, 2, 1);
           substr($out, 2, 1) = substr($in, 1, 1);
       }

       return $out;
    }

# Byte swap a 64-bit number from little-endian to big-endian
    sub byteswap64 {
       # Read in a 8-character string
       my $in = shift;
       my $out = $in;

       if ($Config{'byteorder'} == 4321) {
           substr($out, 4, 4) = byteswap32(substr($in, 0, 4));
           substr($out, 0, 4) = byteswap32(substr($in, 4, 4));
       }

       return $out;
    }

# Opens a .nuv file and returns information about it
    sub nuv_info {
        my $file = shift;
        my(%info, $buffer);
    # open the file
        open(DATA, $file) or die "Can't open $file:  $!\n\n";
    # Read the file info header
        read(DATA, $buffer, 72);
    # Byte swap the buffer
        if ($Config{'byteorder'} == 4321) {
            substr($buffer, 20, 4) = byteswap32(substr($buffer, 20, 4));
            substr($buffer, 24, 4) = byteswap32(substr($buffer, 24, 4));
            substr($buffer, 28, 4) = byteswap32(substr($buffer, 28, 4));
            substr($buffer, 32, 4) = byteswap32(substr($buffer, 32, 4));
            substr($buffer, 40, 8) = byteswap64(substr($buffer, 40, 8));
            substr($buffer, 48, 8) = byteswap64(substr($buffer, 48, 8));
            substr($buffer, 56, 4) = byteswap32(substr($buffer, 56, 4));
            substr($buffer, 60, 4) = byteswap32(substr($buffer, 60, 4));
            substr($buffer, 64, 4) = byteswap32(substr($buffer, 64, 4));
            substr($buffer, 68, 4) = byteswap32(substr($buffer, 68, 4));
        }
    # Unpack the data structure
        ($info{'finfo'},          # "NuppelVideo" + \0
         $info{'version'},        # "0.05" + \0
         $info{'width'},
         $info{'height'},
         $info{'desiredheight'},  # 0 .. as it is
         $info{'desiredwidth'},   # 0 .. as it is
         $info{'pimode'},         # P .. progressive, I .. interlaced  (2 half pics) [NI]
         $info{'aspect'},         # 1.0 .. square pixel (1.5 .. e.g. width=480: width*1.5=720 for capturing for svcd material
         $info{'fps'},
         $info{'videoblocks'},    # count of video-blocks -1 .. unknown   0 .. no video
         $info{'audioblocks'},    # count of audio-blocks -1 .. unknown   0 .. no audio
         $info{'textsblocks'},    # count of text-blocks  -1 .. unknown   0 .. no text
         $info{'keyframedist'}
            ) = unpack('Z12 Z5 xxx i i i i a xxx d d i i i i', $buffer);
    # Perl occasionally over-reads on the previous read()
        seek(DATA, 72, 0);
    # Read and parse the first frame header
        read(DATA, $buffer, 12);
    # Byte swap the buffer
        if ($Config{'byteorder'} == 4321) {
            substr($buffer, 4, 4) = byteswap32(substr($buffer, 4, 4));
            substr($buffer, 8, 4) = byteswap32(substr($buffer, 8, 4));
        }
        my ($frametype,
            $comptype,
            $keyframe,
            $filters,
            $timecode,
            $packetlength) = unpack('a a a a i i', $buffer);
    # Parse the frame
        die "Illegal nuv file format:  $file\n\n" unless ($frametype eq 'D');
    # Read some more stuff if we have to
        read(DATA, $buffer, $packetlength) if ($packetlength);
    # Read the remaining frame headers
        while (12 == read(DATA, $buffer, 12)) {
        # Byte swap the buffer
            if ($Config{'byteorder'} == 4321) {
                substr($buffer, 4, 4) = byteswap32(substr($buffer, 4, 4));
                substr($buffer, 8, 4) = byteswap32(substr($buffer, 8, 4));
            }
        # Parse the frame header
            ($frametype,
             $comptype,
             $keyframe,
             $filters,
             $timecode,
             $packetlength) = unpack('a a a a i i', $buffer);
        # Read some more stuff if we have to
            read(DATA, $buffer, $packetlength) if ($packetlength);
        # Look for the audio frame
            if ($frametype eq 'X') {
            # Byte swap the buffer
                if ($Config{'byteorder'} == 4321) {
                    substr($buffer, 0, 4)  = byteswap32(substr($buffer, 0, 4));
                    substr($buffer, 12, 4) = byteswap32(substr($buffer, 12, 4));
                    substr($buffer, 16, 4) = byteswap32(substr($buffer, 16, 4));
                    substr($buffer, 20, 4) = byteswap32(substr($buffer, 20, 4));
                    substr($buffer, 24, 4) = byteswap32(substr($buffer, 24, 4));
                    substr($buffer, 28, 4) = byteswap32(substr($buffer, 28, 4));
                    substr($buffer, 32, 4) = byteswap32(substr($buffer, 32, 4));
                    substr($buffer, 36, 4) = byteswap32(substr($buffer, 36, 4));
                    substr($buffer, 40, 4) = byteswap32(substr($buffer, 40, 4));
                    substr($buffer, 44, 4) = byteswap32(substr($buffer, 44, 4));
                    substr($buffer, 48, 4) = byteswap32(substr($buffer, 48, 4));
                    substr($buffer, 52, 4) = byteswap32(substr($buffer, 52, 4));
                    substr($buffer, 56, 4) = byteswap32(substr($buffer, 56, 4));
                    substr($buffer, 60, 8) = byteswap64(substr($buffer, 60, 8));
                    substr($buffer, 68, 8) = byteswap64(substr($buffer, 68, 8));
                }
                my $frame_version;
                ($frame_version,
                 $info{'video_type'},
                 $info{'audio_type'},
                 $info{'audio_sample_rate'},
                 $info{'audio_bits_per_sample'},
                 $info{'audio_channels'},
                 $info{'audio_compression_ratio'},
                 $info{'audio_quality'},
                 $info{'rtjpeg_quality'},
                 $info{'rtjpeg_luma_filter'},
                 $info{'rtjpeg_chroma_filter'},
                 $info{'lavc_bitrate'},
                 $info{'lavc_qmin'},
                 $info{'lavc_qmax'},
                 $info{'lavc_maxqdiff'},
                 $info{'seektable_offset'},
                 $info{'keyframeadjust_offset'}
                 ) = unpack('ia4a4iiiiiiiiiiiill', $buffer);
            # Found the audio data we want - time to leave
                 last;
            }
        # Done reading frames - let's leave
            else {
                last;
            }
        }
    # Close the file
        close DATA;
    # Make sure some things are actually numbers
        $info{'width'}  += 0;
        $info{'height'} += 0;
    # HD fix
        if ($info{'height'} == 1080) {
            $info{'height'} = 1088;
        }
    # Make some corrections for myth bugs
        $info{'audio_sample_rate'} = 44100 if ($info{'audio_sample_rate'} == 42501 || $info{'audio_sample_rate'} =~ /^44\d\d\d$/);
    # NEIL Don't know why he hard set it?
    #    $info{'aspect'} = '4:3';
    # Cleanup
        $info{'aspect'}   = aspect_str($info{'aspect'});
        $info{'aspect_f'} = aspect_float($info{'aspect'});
    # Return
        return %info;
    }

    sub aspect_str {
        my $aspect = shift;
    # Already in ratio format
        return $aspect if ($aspect =~ /^\d+:\d+$/);
    # European decimals...
        $aspect =~ s/\,/\./;
    # Parse out decimal formats
        if ($aspect == 1)          { return '1:1';    }
        elsif ($aspect =~ m/^1.3/) { return '4:3';    }
        elsif ($aspect =~ m/^1.7/) { return '16:9';   }
        elsif ($aspect == 2.21)    { return '2.21:1'; }
    # Unknown aspect
        print STDERR "Unknown aspect ratio:  $aspect\n";
        return $aspect.':1';
    }

    sub aspect_float {
        my $aspect = shift;
    # European decimals...
        $aspect =~ s/\,/\./;
    # In ratio format -- do the math
        if ($aspect =~ /^\d+:\d+$/) {
            my ($w, $h) = split /:/, $aspect;
            return $w / $h;
        }
    # Parse out decimal formats
        if ($aspect eq '1')        { return  1;     }
        elsif ($aspect =~ m/^1.3/) { return  4 / 3; }
        elsif ($aspect =~ m/^1.7/) { return 16 / 9; }
    # Unknown aspect
        return $aspect;
    }

my %info = nuv_info($ENV{'NUVINFOFILE'});
my $c = 0;
foreach my $key (split(' ', $ENV{'NUVINFOPROPS'})) {
	($c++ < 1) and print "$info{$key}" or print ":$info{$key}";
}
print "\n";
#ENDNUVINFO

###########################################################################################################
License Notes:
--------------

This software product is licensed under the GNU General Public License
(GPL). This license gives you the freedom to use this product and have
access to the source code. You can modify this product as you see fit
and even use parts in your own software. If you choose to do so, you
also choose to accept that a modified product or software that use any
code from mythnuv2mkv.sh MUST also be licensed under the GNU General Public
License.

In plain words, you can NOT sell or distribute mythnuv2mkv.sh, a modified
version or any software product based on any parts of mythnuv2mkv.sh as a
closed source product. Likewise you cannot re-license this product and
derivates under another license other than GNU GPL.

See also the article, "Free Software Matters: Enforcing the GPL" by
Eben Moglen. http://emoglen.law.columbia.edu/publications/lu-13.html
###########################################################################################################