View difference between Paste ID: ENMjrLKr and
SHOW: | | - or go back to the newest paste.
1-
1+
#!/bin/bash
2
# @(#)$Header: /home/mythtv/mythtvrep/scripts/mythnuv2mkv.sh,v 1.61 2010/10/09 21:06:19 mythtv Exp $
3
# Auric 2007/07/10 http://web.aanet.com.au/auric/
4
# source the config file
5
[ -f $(dirname "$0")/mythnuv2mkv.cfg ] && . $(dirname "$0")/mythnuv2mkv.cfg
6
7
##########################################################################################################
8
#
9
# Convert MythRecording & MythVideo nuv or mpg files to mkv mp4 or avi.
10
#
11
######### Vars you may want to set for your environment, put them in mythnuv2mkv.cfg along with this script ##
12
13
# Default aspect for Myth Recording mpg files. It will try to work it out but if it can't will use this.
14
readonly DEFAULTMPEG2ASPECT="${DEFAULTMPEG2ASPECT-NA}" # 4:3 or 16:9
15
# Log directory
16
readonly LOGBASEDIR="${LOGBASEDIR-/var/tmp}" # Don't use a directory with spaces in it's name
17
# Number of errors reported by mplayer allowed in the transcoded file
18
readonly MPLAYER_ERROR_COUNT="${MPLAYER_ERROR_COUNT-8}"
19
# Path to your mysql.txt file
20
readonly MYSQLTXT="${MYSQLTXT-}"
21
# What to separate title, subtitle etc. with
22
readonly SEP="${SEP-,}"
23
# What (if at all) to replace spaces with
24
readonly TR="${TR-_}"
25
# printf(episode_number)
26
readonly EPISODE_FORMAT="${EPISODE_FORMAT-E%02d}"
27
# printf(formatted_episode, season_number)
28
readonly SEASON_FORMAT="${SEASON_FORMAT-S%2\$02d%1\$s }"
29
# printf(title, formatted_season_episode)
30
readonly TITLE_FORMAT="${TITLE_FORMAT-%s %s}"
31
# printf(filename, date)
32
readonly DATE_FORMAT="${DATE_FORMAT-%s [%s]}"
33
# RegEx for matching season/episode numbers
34
readonly EPISODE_RE="${EPISODE_RE-^S[0-9]+E[0-9]+ $}"
35
# Chapter marks every X minutes
36
CHAPTERDURATION="${CHAPTERDURATION-0}"
37
# Crop input
38
CROP="${CROP-ON}" # ON | OFF, can also change with --crop argument
39
CROPSIZE="${CROPSIZE-8}"
40
# Delete recording after successful transcode. Only for transcode out of MythRecording. (Actually just sets to high priority autoexpire.)
41
DELETEREC="${DELETEREC-OFF}" # ON | OFF, can also change with --deleterec argument
42
# Include denoise filter
43
DENOISE="${DENOISE-OFF}" # ON | OFF, can also change with --denoise argument
44
# Include deblock filter
45
DEBLOCK="${DEBLOCK-OFF}" # ON | OFF, can also change with --deblock argument
46
# Include deinterlace filter.
47
# SOURCENAME is ON for that source. Can have multiple. e.g. DEINTERLACE="Cabel,FTA1"
48
DEINTERLACE="${DEINTERLACE-ON}" # ON | OFF | SOURCENAME,SOURCENAME can also change with --deinterlace argument.
49
# Include inverse Telecine filter (Experimental. Can someone from NTSC/ATSC land try this?).
50
# invtelecine filter is never added if deinterlace has been added.
51
INVTELECINE="${INVTELECINE-OFF}" # ON | OFF, can also change with --invtelecine argument.
52
# number passes
53
PASS="${PASS-two}" # one | two, can also change with --pass argument
54
# number of threads. Only used by lavc and xvid (x.264 auto calculates threads)
55
THREADS="${THREADS-1}"
56
# avi encoder lavc or xvid
57
AVIVID="${AVIVID-lavc}" # lavc | xvid, can also change with --contype=avi,xvid argument
58
# container
59
CONTYPE="${CONTYPE-mkv}" # mkv | mp4 | avi, can also change with --contype argument or name of script.
60
# mkv audio encoder aac or ogg
61
MKVAUD="${MKVAUD-aac}" # aac | ogg, can also change with --contype=mkv,ogg argument
62
# audio tracks with, optionally, their language code, in the order they are to be added to the resulting file
63
# language codes and multiple tracks only supported in mp4 and mkv
64
ATRACKS="${ATRACKS-0}" # n[:lng][,m[:lng]]..., can also change with --audiotracks
65
# add your own filters if you want
66
POSTVIDFILTERS="${POSTVIDFILTERS-}"	#must include , at end
67
ENDVIDFILTERS="${ENDVIDFILTERS-}"	#must include , at end
68
# Disable some output checks. Can have multiple. e.g. OUTPUTCHECKS="NOSIZERATIO,NOSCAN"
69
OUTPUTCHECKS="${OUTPUTCHEKS-}" # NOSIZE,NOVIDINFO,NOSIZERATIO,NOFRAMECOUNT,NOSCAN can also change with --outputchecks argument.
70
# Boinc passwd, if you run boinc and want to disable it during transcode
71
readonly BOINCPASSWD="${BOINCPASSWD-}"
72
# Use mediainfo if available to identify video properties.
73
USEMEDIAINFO="${USEMEDIAINFO-TRUE}" # TRUE or FALSE
74
# default quality profile
75
QUALITY="${QUALITY-med}"
76
77
#
78
PATH=~mythtv/bin:${HOME}/bin:$PATH:/usr/local/bin
79
# these variables will be recalled, if temporarily overriden, on every file change
80
RECALL="ASPECTINLINE DENOISE POSTVIDFILTERS DEBLOCK DEINTERLACE INVTELECINE CROP CROPSIZE DELETEREC CHAPTERDURATION \
81
CHAPTERFILE COPYDIR CONTYPE QUICKTIME_MP4 MKVAUD AVIVID PASS SCALE43 SCALE169 LAVC_CQ LAVC_OPTS XVID_CQ XVID_OPTS \
82
MP3_ABITRATE X264_CQ X264EXT_OPTS X264_OPTS AAC_AQUAL OGG_AQUAL ATRACKS TITLE SUBTITLE"
83
# these variables will be clean on every file change
84
CLEAN="META_SEASON META_EPISODE META_ARTIST META_DIRECTOR META_ALBUM META_COMMENT META_LOCATION META_DATE" 
85
	
86
87
##### Mapping #############################################################################################
88
# Maps tvguide categories to mythvideo ones. This will need to be managed individually.
89
# Either use the defaults below or create a mythnuv2mkv-category-mappings file in the same
90
# directory as this and enter data same format as below.
91
readonly CMAPFILE="$(dirname ${0})/mythnuv2mkv-category-mappings"
92
if [ -f "$CMAPFILE" ]
93
then 
94
	. "$CMAPFILE"
95
else
96
	# NOTE: Remove any spaces from XMLTV category. e.g. "Mystery and Suspense" is MysteryandSuspense
97
	# XMLTV Category		 ; Myth videocategory
98
	readonly Animated=1		 ; mythcat[1]="Animation"
99
	readonly Biography=2		 ; mythcat[2]="Documentary"
100
	readonly Historical=3		 ; mythcat[3]="Documentary"
101
	readonly CrimeDrama=4		 ; mythcat[4]="CrimeDrama"
102
	readonly MysteryandSuspense=5	 ; mythcat[5]="Mystery"
103
	readonly Technology=6		 ; mythcat[6]="Documentary"
104
	readonly ScienceFiction=7	 ; mythcat[7]="Sci-Fi"
105
	readonly Science_Fiction=8	 ; mythcat[8]="Sci-Fi"
106
	readonly art=9			 ; mythcat[9]="Musical"
107
	readonly History=10		 ; mythcat[10]="Documentary"
108
	readonly SciFi=11		 ; mythcat[11]="Sci-Fi"
109
	readonly ScienceNature=12	 ; mythcat[12]="Science"
110
fi
111
112
##########################################################################################################
113
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] [--aspect=4:3|16:9] [--crop=ON|OFF] [--deinterlace=ON|OFF|SOURCENAME] [--invtelecine=ON|OFF] [--outputchecks=notype] [[--chapterduration=mins] | [--chapterfile=file]] [--maxrunhours=int] [--findtitle=string] [--copydir=directory] "--chanid=chanid --starttime=starttime" | file ...
114
Must have either --chanid=chanid and --starttime=starttime or a plain filename. These can be mixed. e.g. -
115
mythnuv2mkv.sh --chanid=1232 --starttime=20071231235900 video1 video2 --chanid=1235 --starttime=20071231205900
116
--jobid=%JOBID%
117
        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.
118
--contype=avi|mkv|mp4 (default name of script. e.g. mythnuv2mkv.sh will default to mkv. mythnuv2avi.sh will default to avi)
119
	(Note Videos staying in MythRecord will always default to avi)
120
	avi - Video mpeg4 Audio mp3 (--contype=avi,xvid will use xvid instead of lavc)
121
	mkv - Video h.264 Audio aac (--contype=mkv,ogg will use ogg Vorbis Audio)
122
	mp4 - Video h.264 Audio aac
123
--quality=low|med|high|720|1080 (default med) Mostly affects resolution.
124
	low  - 448x336(4:3) or 592x336(16:9)
125
	med  - 512x384(4:3) or 624x352(16:9)
126
	high - 528x400(4:3) or 656x368(16:9)
127
	480  - 640x480(4:3) or 848x480(16:9)
128
	576  - 768x576(4:3) or 1024x576(16:9)
129
	720  - 1280x720(16:9) (You probably need VDAPU to play this)
130
	1080 - 1920x1088(16:9) (You probably need VDAPU to play this)
131
--pass=one|two (default two)
132
	--quality --pass and --contype can be passed as any argument and will only take effect on files after them.
133
	e.g. mythnuv2mkv.sh videofile1 --chanid=2033 --starttime=20070704135700 --pass=one video3 --quality=low video4
134
	videofile1 and chanid=2033/starttime=20070704135700 will be two pass med quality (defaults)
135
	video3, one pass med quality
136
	video4, one pass low quality
137
--audiotracks=n[:lng][,m[:lng]]... (default empty)
138
	audio tracks and, optionally, their language code, in the order they are supposed to be added to the output file (language codes and multiple tracks only supported in mp4 and mkv),
139
	empty means one track, whichever mythtranscode chooses by default
140
--maxrunhours=int (default process all files)
141
	Stop processing files after int hours. (Will complete the current file it is processing.)
142
--findtitle="string"
143
	Prints tile, chanid, starttime of programs matching string.
144
--copydir=directory
145
	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.
146
	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.
147
	For MythTV 0.21 - 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.
148
	For MythTV 0.22 - If directory is under MythVideoDir, no action taken. Use MythVideo tools, e.g. Metadata menu, jamu.
149
--denoise=[ON|OFF] (default OFF)
150
	Include hqdn3d denoise filter.	
151
--deblock=[ON|OFF] (default OFF)
152
	Include pp7 deblock filter.	
153
--deleterec=[ON|OFF] (default OFF)
154
	Delete the recording after successful transcode. (Actually just sets high priority autoexpire and moves to Deleted group.)
155
--crop=[ON|OFF] (default ON)
156
	Crop 8 pixels of each side.	
157
--aspect=[4:3|16:9] Force aspect.
158
--deinterlace==[ON|OFF|SOURCENAME] (default ON)
159
	Include pp=fd deinterlace filter.
160
	SOURCENAME is ON for that source. Can have multiple. e.g. DEINTERLACE="Cabel,FTA1"
161
--invtelecine=[ON|OFF] (default OFF)
162
	Include pullup inverse telecine filter.
163
	Note/ This filter will not be added if a deinterlace filter has been added.
164
--outputchecks=[NOSIZE,NOVIDINFO,NOSIZERATIO,NOFRAMECOUNT,NOSCAN] (default All checks ON)
165
	Disable a output check. Set to one or many of the checks. e.g. OUTPUTCHECKS="NOSIZERATIO,NOSCAN"
166
---chapterduration=mins
167
	Add chapter marks to mkv/mp4 files every mins minutes.
168
---chapterfile=file
169
	Add chapter marks to mkv/mp4 as per chapter file. See mkvmerge or MP4Box manual for chapter file format.
170
	(spaces not supported in chapter file name)
171
172
Logs to /var/tmp/mythnuv2mkvPID.log and to database if "log MythTV events to database" is enabled in mythtv.
173
Cutlists are always honored.
174
Sending the mythnuv2mkv.sh process a USR1 signal will cause it to stop after completing the current file.
175
e.g. kill -s USR1 PID
176
If run as a Myth Job, you can find the PID in the System Status Job Queue or Log Entries screens as [PID]
177
178
Typical usage.
179
180
Myth User Job
181
PATH/mythnuv2mkv.sh --jobid=%JOBID% --copydir /mythvideodirectory --chanid=%CHANID% --starttime=%STARTTIME%
182
This will convert nuv to mkv and copy it to /mythvideodirectory.
183
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.
184
NOTE. System Status Job Queue screen and the Job Queue Comments field in MythWeb always report job Completed Successfully even if it actually failed.
185
186
Myth Video
187
Record program
188
mythrename.pl --link --format %T-%S --underscores --verbose (mythrename.pl is in the mythtv contrib directory
189
cp from your mythstore/show_names/PROGRAM to your MythVideo directory
190
use video manager to add imdb details 
191
nuv files work fine in MythVideo, but if you need to convert them to mkv/mp4/avi, or need to reduce their size
192
run mythnuv2mkv.sh MythVideo_file.nuv
193
194
Myth Recording
195
Record program
196
run mythnuv2mkv.sh --findtitle="title name"
197
get chanid and starttime
198
run mythnuv2mkv.sh --chanid=chanid --starttime=starttime
199
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.
200
NOTE You cannot play a mkv/mp4 file in Myth Recording.
201
I would in general recommend leaving everything in Myth Recording as nuv.
202
203
You can override most options for a specific recording by adding tags to the subtitle in MythTV, for example a subtitle of the form:
204
  "Some subtitle r|David Lynch q|1080 f|mp4 crop|NO"
205
  Will result in:
206
    - subtitle:"Some subtitle"
207
    - director: "David Lynch"
208
    - quality: 1080
209
    - container: mp4
210
    - crop: NO
211
  Available tags:
212
    t: title
213
    s: subtitle / episode title
214
    n: season number
215
    e: episode number
216
    a: artist
217
    r: director
218
    b: album
219
    c: comment
220
    l: location
221
    y|d: year / date (YYYY / YYYY-MM-DD / DD-MM-YYYY / DD.MM.YYYY etc.)
222
    q: quality
223
    f: container format
224
    aud: audio track definitions
225
    asp: aspect ratio
226
    den: denoise filter
227
    deb: deblock filter
228
    dei: deinterlace
229
    inv: inverse telecine
230
    crop: cropping
231
    del: delete recording
232
    chap: chapter length
233
    chapf: chapter file
234
    dir: copy directory
235
    pass: encoding pass count
236
237
Version: $Revision: 1.91 (beta) $ $Date: 2011/03/23 01:13:12 $
238
'
239
REQUIREDAPPS='
240
Required Applications
241
For all contypes
242
mythtranscode.
243
perl
244
mplayer http://www.mplayerhq.hu/design7/news.html
245
mencoder http://www.mplayerhq.hu/design7/news.html
246
wget http://www.gnu.org/software/wget/
247
ImageMagick http://www.imagemagick.org/script/index.php
248
For avi
249
mp3lame http://www.mp3dev.org
250
xvid http://www.xvid.org/
251
For mkv and mp4 contypes
252
x264 http://www.videolan.org/developers/x264.html
253
faac http://sourceforge.net/projects/faac/
254
faad2 http://sourceforge.net/projects/faac/
255
For mkv contype
256
mkvtoolnix http://www.bunkus.org/videotools/mkvtoolnix/
257
For mkv,ogg contype
258
vorbis-tools http://www.vorbis.com/
259
For mp4 contype
260
MP4Box http://gpac.sourceforge.net/index.php
261
'
262
HELP=${USAGE}${REQUIREDAPPS}
263
264
##### Pre Functions ###########################################
265
preversioncheck() {
266
local PRODUCT="$1"
267
local LIBX264
268
	case $PRODUCT in
269
		libx264)
270
			LIBX264=$(ldd $(which mencoder) | awk '/libx264/ {print $3}')
271
			if strings "$LIBX264" | grep MB-tree >/dev/null 2>&1
272
			then
273
				# Actually won't be used as currently (23/11/09) b_pyramid is disabled when MB-tree used
274
				# At some point b_pyramid may be added, so leaving this in
275
				NOBPYRAMID="b_pyramid=none:" # Global
276
				BPYRAMID="b_pyramid=normal:" # Global
277
			else
278
				NOBPYRAMID="nob_pyramid:" # Global
279
				BPYRAMID="b_pyramid:" # Global
280
			fi
281
			if strings "$LIBX264" | grep force-cfr >/dev/null 2>&1
282
			then
283
				FORCECFR="force_cfr:" # Global
284
			else
285
				FORCECFR="" # Global
286
			fi
287
               ;;
288
	esac
289
}
290
291
###########################################################
292
readonly AVIREQPROGS="mencoder mythtranscode mplayer perl wget convert"
293
readonly AVIREQLIBS="libmp3lame.so libxvidcore.so"
294
readonly MP4REQPROGS="mencoder mythtranscode mplayer perl wget convert faac MP4Box"
295
readonly MP4REQLIBS="libx264.so"
296
readonly MKVREQPROGS="mencoder mythtranscode mplayer perl wget convert faac oggenc mkvmerge"
297
readonly MKVREQLIBS="libx264.so"
298
###########################################################
299
readonly DENOISEFILTER="hqdn3d"
300
readonly DEBLOCKFILTER="pp7"
301
readonly DEINTERLACEFILTER="pp=fd"
302
readonly INVTELECINEFILTER="pullup"
303
readonly FAACCHANCONFIG="-I 5,6"
304
readonly TE_SCALE43="NA"		# NA
305
readonly ST_SCALE43="NA"		# NA
306
readonly FE_SCALE43="640:480"		# 1.32
307
readonly FS_SCALE43="768:576"		# 1.32
308
readonly HIGH_SCALE43=528:400		# 1.32
309
readonly MED_SCALE43=512:384		# 1.333
310
readonly LOW_SCALE43=448:336		# 1.333
311
readonly TE_SCALE169="1920:1088" 	# 1.778
312
readonly ST_SCALE169="1280:720"		# 1.778
313
readonly FE_SCALE169="848:480" 		# 1.766
314
readonly FS_SCALE169="1024:576" 	# 1.778
315
readonly HIGH_SCALE169=656:368		# 1.783
316
readonly MED_SCALE169=624:352		# 1.773
317
readonly LOW_SCALE169=592:336		# 1.762
318
# Default
319
SCALE43=$MED_SCALE43
320
SCALE169=$MED_SCALE169
321
###########################################################
322
## CQ ## Quote from mencoder documentation
323
#The CQ depends on the bitrate, the video codec efficiency and the movie resolution. In order to raise the CQ, typically you would
324
#downscale the movie given that the bitrate is computed in function of the target size and the length of the movie, which are constant.
325
#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
326
#not enough bits to code the information of each macroblock. (MPEG4, like many other codecs, groups pixels by blocks of several pixels
327
#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
328
# 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
329
#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
330
#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
331
#encoding options, and should be able to go as low as 0.10 to 0.12 with x264's advanced encoding settings.
332
########################
333
# These map to --quality=low|med|high option.
334
#### AVI lavc mpeg4 ####
335
readonly HIGH_LAVC_CQ=0.22
336
readonly MED_LAVC_CQ=0.21
337
readonly LOW_LAVC_CQ=0.20
338
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"
339
# high, med & low will use same settings just CQ and resolution different
340
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
341
#readonly MED_LAVC_OPTS="vcodec=mpeg4:mbd=2:trell:v4mv"
342
#readonly LOW_LAVC_OPTS="vcodec=mpeg4:mbd=2"
343
readonly MED_LAVC_OPTS="$HIGH_LAVC_OPTS"
344
readonly LOW_LAVC_OPTS="$HIGH_LAVC_OPTS"
345
#### AVI xvid mpeg4 ####
346
readonly HIGH_XVID_CQ=0.22
347
readonly MED_XVID_CQ=0.21
348
readonly LOW_XVID_CQ=0.20
349
readonly HIGH_XVID_OPTS="threads=${THREADS}:quant_type=mpeg:me_quality=6:chroma_me:chroma_opt:trellis:hq_ac:vhq=4:bvhq=1"
350
readonly MED_XVID_OPTS="$HIGH_XVID_OPTS"
351
readonly LOW_XVID_OPTS="$HIGH_XVID_OPTS"
352
#### AVI lavc/xvid mp3 ####
353
readonly HIGH_MP3_ABITRATE=256
354
readonly MED_MP3_ABITRATE=192
355
readonly LOW_MP3_ABITRATE=128
356
#### MP4/MKV h.263/aac,ogg ####
357
readonly HIGH_X264_CQ=0.15
358
readonly MED_X264_CQ=0.14
359
readonly LOW_X264_CQ=0.13
360
preversioncheck "libx264" # Sets BPYRAMID & NOBPYRAMID & FORCECFR
361
# H.264 Extended profile (quicktime) level set in QLEVEL
362
readonly HIGH_X264EXT_OPTS="nocabac:bframes=2:${FORCECFR}${NOBPYRAMID}threads=auto:direct_pred=auto:subq=6:frameref=5"
363
# high, med & low will use same settings just CQ and resolution different
364
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
365
#readonly MED_X264EXT_OPTS="nocabac:bframes=2:${FORCECFR}${NOBPYRAMID}threads=auto:subq=5:frameref=4"
366
#readonly LOW_X264EXT_OPTS="nocabac:bframes=2:${FORCECFR}${NOBPYRAMID}threads=auto:subq=4:frameref=3"
367
readonly MED_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
368
readonly LOW_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
369
# H.264 High profile level set in QLEVEL
370
readonly HIGH_X264HIGH_OPTS="bframes=3:${FORCECFR}${BPYRAMID}weight_b:threads=auto:direct_pred=auto:subq=6:frameref=5:partitions=all:8x8dct:mixed_refs:me=umh:trellis=1"
371
# high, med & low will use same settings just CQ and resolution different
372
# This make encoding slow. Swap following if you want lower quality to also mean faster encoding speed.
373
#readonly MED_X264HIGH_OPTS="bframes=3:${FORCECFR}${BPYRAMID}weight_b:threads=auto:subq=5:frameref=4:8x8dct"
374
#readonly LOW_X264HIGH_OPTS="bframes=3:${FORCECFR}${BPYRAMID}weight_b:threads=auto:subq=4:frameref=3"
375
readonly MED_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
376
readonly LOW_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
377
# AAC
378
readonly HIGH_AAC_AQUAL=100
379
readonly MED_AAC_AQUAL=90
380
readonly LOW_AAC_AQUAL=80
381
# OGG
382
readonly HIGH_OGG_AQUAL=6
383
readonly MED_OGG_AQUAL=5
384
readonly LOW_OGG_AQUAL=4
385
# Defaults
386
LAVC_OPTS=$MED_LAVC_OPTS
387
LAVC_CQ=$MED_LAVC_CQ
388
XVID_OPTS=$MED_XVID_OPTS
389
XVID_CQ=$MED_XVID_CQ
390
MP3_ABITRATE=$MED_MP3_ABITRATE
391
AAC_AQUAL=$MED_AAC_AQUAL
392
OGG_AQUAL=$MED_OGG_AQUAL
393
X264EXT_OPTS="level_idc=31:$MED_X264EXT_OPTS"
394
X264_OPTS="level_idc=31:$MED_X264HIGH_OPTS"
395
X264_CQ=$MED_X264_CQ
396
if echo "$(basename $0)" | grep -i 'mkv' >/dev/null 2>&1
397
then
398
	CONTYPE="mkv"
399
	QUICKTIME_MP4="NO"
400
elif echo "$(basename $0)" | grep -i 'mp4' >/dev/null 2>&1
401
then
402
	CONTYPE="mp4"
403
	QUICKTIME_MP4="NO"
404
elif echo "$(basename $0)" | grep -i 'mov' >/dev/null 2>&1
405
then
406
	#TODO. Not working yet don't use mov
407
	CONTYPE="mp4"
408
	QUICKTIME_MP4="YES"
409
elif echo "$(basename $0)" | grep -i 'avi' >/dev/null 2>&1
410
then
411
	CONTYPE="avi"
412
	QUICKTIME_MP4="NO"
413
fi
414
###########################################################
415
# ON or OFF
416
# debug mode
417
DEBUG="OFF"
418
DEBUGSQL="OFF"
419
DEBUGSG="OFF"
420
# Print INFO messages
421
INFO="ON"
422
# Save(via a rename) or delete nuv file. Only for transcode back into MythRecording.
423
SAVENUV="OFF"
424
425
[ "$DEBUGSQL" = "ON" ] && DEBUG="ON"
426
427
##### Functions ###########################################
428
scriptlog() {
429
local LEVEL="$1"
430
shift
431
local PRIORITY
432
local HIGHLIGHTON
433
local HIGHLIGHTOFF
434
	if [ "$LEVEL" = "BREAK" ]
435
	then
436
		echo "--------------------------------------------------------------------------------" | tee -a $LOGFILE
437
		return 0
438
	elif [ "$LEVEL" = "ERROR" ]
439
	then
440
		PRIORITY=4
441
		HIGHLIGHTON="${REDFG}"
442
		HIGHLIGHTOFF="${COLOURORIG}"
443
		FINALEXIT=1 # Global
444
	elif [ "$LEVEL" = "WARN" ]
445
	then
446
		PRIORITY=4
447
		HIGHLIGHTON="${REDFG}"
448
		HIGHLIGHTOFF="${COLOURORIG}"
449
	elif [ "$LEVEL" = "SUCCESS" ]
450
	then
451
		PRIORITY=5
452
		HIGHLIGHTON="${GREENFG}"
453
		HIGHLIGHTOFF="${COLOURORIG}"
454
	elif [ "$LEVEL" = "START" -o "$LEVEL" = "STOP" ]
455
	then
456
		PRIORITY=5
457
		HIGHLIGHTON="${BOLDON}"
458
		HIGHLIGHTOFF="${ALLOFF}"
459
	elif [ "$LEVEL" = "DEBUG" ]
460
	then
461
		[ "$DEBUG" = "ON" ] || return
462
		PRIORITY=7
463
		HIGHLIGHTON=""
464
		HIGHLIGHTOFF=""
465
	elif [ "$LEVEL" = "NOHEADER" ]
466
	then
467
		# Also no db logging
468
		echo "$*" | tee -a $LOGFILE
469
		return
470
	else
471
		[ "$INFO" = "ON" ] || return
472
		LEVEL="INFO"
473
		PRIORITY=6
474
		HIGHLIGHTON=""
475
		HIGHLIGHTOFF=""
476
	fi
477
	echo "${HIGHLIGHTON}$(date +%d/%m,%H:%M) [${$}] $LEVEL $*${HIGHLIGHTOFF}" | tee -a $LOGFILE
478
479
	[ "$DBLOGGING" -eq 1 ] && insertmythlogentry "$PRIORITY" "$LEVEL" "${$}" "$*"
480
}
481
482
versioncheck() {
483
local PRODUCT="$1"
484
local VER
485
local MAJ
486
local MIN
487
local PAT
488
	case $PRODUCT in
489
		mkvmerge)
490
			VER=$(mkvmerge -V | awk '/mkvmerge/ {print $2}')
491
			OLDIFS="$IFS"; IFS="."; set - $VER; IFS="$OLDIFS"
492
			MAJ=$(echo "$1" | tr -d '[:alpha:]'); MIN="$2"; PAT="$3"
493
			if [ "$VER" = "v2.5.1" ]
494
			then
495
				scriptlog INFO "mkvmerge v2.5.1. There is a known bug with this version. Workaround applied."
496
				MKVMERGE251BUG="YES" # Global
497
			elif [ "$MAJ" -lt 2 -o \( "$MAJ" -eq 2 -a "$MIN" -lt 2 \) ]
498
			then
499
				scriptlog INFO "mkvmerge $VER. This will not work with 29.97 fps video (NTSC). You need at least v2.2.0"
500
			fi
501
			scriptlog DEBUG "mkvmerge $VER"
502
			return 0
503
		;;
504
		convert)
505
			# There are several programs called convert. Check it is ImageMagick.
506
			convert -version 2>&1 | grep -i 'ImageMagick' >/dev/null 2>&1 && return 0 || return 1
507
		;;
508
	esac
509
}
510
511
chkreqs() {
512
local REQPROGS="$1"
513
local REQLIBS="$2"
514
local TMP
515
local MENCODER
516
	for TMP in $REQPROGS
517
	do
518
		if ! which "$TMP" >/dev/null 2>&1
519
		then
520
			scriptlog ERROR "Can't find program $TMP."
521
			scriptlog ERROR "$REQUIREDAPPS"
522
			return 1
523
		fi
524
	done
525
	MENCODER=$(which mencoder)
526
	for TMP in $REQLIBS
527
	do
528
		if ! ldd $MENCODER | grep -i  "${TMP}.*=>.*${TMP}" >/dev/null 2>&1
529
		then
530
			scriptlog ERROR "mencoder may not support $TMP."
531
			scriptlog ERROR "$REQUIREDAPPS"
532
			return 1
533
		fi
534
	done
535
	return 0
536
}
537
538
calcbitrate() {
539
local ASPECT=$1
540
local SCALE=$2
541
local CQ=$3
542
local W
543
local H
544
local BITRATE
545
	W=$(echo $SCALE | cut -d ':' -f1)
546
	H=$(echo $SCALE | cut -d ':' -f2)
547
	BITRATE=$(echo "((($H^2 * $ASPECT * 25 * $CQ) / 16 ) * 16) / 1000" | bc)
548
	echo $BITRATE
549
}
550
551
getsetting() {
552
local VALUE="$1"
553
local HOST=$(hostname)
554
local DATA
555
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
556
	select data from settings where value = "$VALUE" and hostname like "${HOST}%";
557
	EOF
558
	)
559
	if [ -z "$DATA" ]
560
	then
561
		DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
562
		select data from settings where value = "$VALUE" and (hostname is NULL or hostname = "");
563
	EOF
564
	)
565
	fi
566
	echo "$DATA"
567
}
568
569
# Not Used.
570
getstoragegroupdirs() {
571
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
572
	select distinct dirname from storagegroup;
573
	EOF
574
}
575
576
hascutlist() {
577
local CHANID="$1"
578
local STARTTIME="$2"
579
local DATA
580
	[ -n "$CHANID" ] || return 1
581
	DATA=$(mysql --batch --skip-column-name --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
582
	select cutlist from recorded where chanid = $CHANID and starttime = "$STARTTIME";
583
	EOF
584
	)
585
	[ "$DATA" -eq 1 ] && return 0 || return 1
586
}
587
588
getrecordfile() {
589
local CHANID="$1"
590
local STARTTIME="$2"
591
local DEBUGSG="$3"
592
local DATA
593
local DATALINE
594
local RECFILE
595
local SGHOST
596
	[ -n "$CHANID" ] || return 1
597
	# Storage groups
598
	if [ "$DEBUGSG" = "ON" ] 
599
	then
600
		scriptlog INFO "CHANID $CHANID STARTTIME $STARTTIME"
601
		DATA=$(mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
602
		select * from storagegroup;
603
		select chanid,starttime,title,subtitle,basename,storagegroup from recorded where chanid = $CHANID and starttime = "$STARTTIME";
604
		EOF
605
		)
606
		scriptlog INFO "Tables"
607
		scriptlog NOHEADER "$DATA"
608
	fi
609
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
610
	select a.hostname,':::',concat(a.dirname, "/", b.basename) from storagegroup a, recorded b where b.chanid = $CHANID and b.starttime = "$STARTTIME" and b.storagegroup = a.groupname;
611
	EOF
612
	)
613
	[ "$DEBUGSG" = "ON" ] && scriptlog INFO "Try 1 Data $DATA"
614
	while read DATALINE
615
	do
616
		SGHOST=$(echo "$DATALINE" | awk -F':::' '{print $1}' | sed -e 's/[ \t]*\(.*\)[ \t]*/\1/')
617
		RECFILE=$(echo "$DATALINE" | awk -F':::' '{print $2}' | sed -e 's/[ \t]*\(.*\)[ \t]*/\1/')
618
		[ "$DEBUGSG" = "ON" ] && scriptlog INFO "Try 1 Check SGHost $SGHOST RecFile $RECFILE"
619
		[ -f "${RECFILE}" ] && break
620
	done < <(echo "$DATA")
621
	if [ ! -f "$RECFILE" ]
622
	then
623
		# Pre Storage groups
624
		local RFP=$(getsetting RecordFilePrefix)
625
		DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
626
		select concat("$RFP", "/", basename) from recorded where chanid = $CHANID and starttime = "$STARTTIME" limit 1;
627
		EOF
628
		)
629
		[ "$DEBUGSG" = "ON" ] && scriptlog INFO "Try 2 $RFP,$DATA"
630
		RECFILE="$DATA"
631
	fi
632
	[ -f "$RECFILE" ] && echo "$RECFILE"
633
}
634
635
getsourcename() {
636
local CHANID="$1"
637
	[ -n "$CHANID" ] || return 1
638
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
639
	select b.displayname from channel a, cardinput b where a.chanid = $CHANID and a.sourceid = b.sourceid;
640
	EOF
641
}
642
643
gettitle() {
644
local CHANID="$1"
645
local STARTTIME="$2"
646
	[ -n "$CHANID" ] || return 1
647
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
648
	select title from recorded where chanid = $CHANID and starttime = "$STARTTIME";
649
	EOF
650
}
651
652
getsubtitle() {
653
local CHANID="$1"
654
local STARTTIME="$2"
655
	[ -n "$CHANID" ] || return 1
656
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
657
	select subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
658
	EOF
659
}
660
661
findchanidstarttime() {
662
local SEARCHTITLE="$1"
663
	mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
664
	select title, subtitle, chanid, date_format(starttime, '%Y%m%d%H%i%s'), storagegroup from recorded where title like "%${SEARCHTITLE}%";
665
	EOF
666
}
667
668
updatemetadata() {
669
local NEW="$1"
670
local CHANID="$2"
671
local STARTTIME="$3"
672
local NFSIZE
673
	NFSIZE=$(stat -c %s "$NEW")
674
	NEW=$(basename "$NEW")
675
	mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
676
	update recorded set
677
	basename = "$NEW",
678
	filesize = $NFSIZE,
679
	bookmark = 0,
680
	editing = 0,
681
	cutlist = 0,
682
	commflagged = 0
683
	where chanid = $CHANID and starttime = "$STARTTIME";
684
	delete from recordedmarkup where chanid = $CHANID and starttime = "$STARTTIME";
685
	delete from recordedseek where chanid = $CHANID and starttime = "$STARTTIME";
686
	EOF
687
}
688
689
createvideocover() {
690
local CFDIR="$1"
691
local FILENAME="$2"
692
local ASPECT="$3"
693
local THDIR="${FIFODIR}/THDIR"
694
local THUMB_NAME=$(basename "$FILENAME" | sed -e 's/\.[am][vkp][iv4]$/\.png/')
695
local THUMB_PATH="${CFDIR}/${THUMB_NAME}"
696
local CURWD
697
local TH
698
	{
699
	CURWD=$(pwd)
700
	mkdir $THDIR && cd $THDIR || return 1
701
	nice -19 mplayer -really-quiet -nojoystick -nolirc -nomouseinput -ss 00:02:00 -aspect $ASPECT -ao null -frames 50 -vo png:z=5 "$FILENAME"
702
	TH=$(ls -1rt | tail -1)
703
	[ -f "$TH" ] || return
704
	if [ $ASPECT = "16:9" ]
705
	then
706
		convert "$TH" -resize 720x404! THWS.png
707
	else
708
		cp "$TH" THWS.png
709
	fi
710
	mv THWS.png "$THUMB_PATH"
711
	cd $CURWD
712
	rm -rf "$THDIR"
713
	} >/dev/null 2>&1
714
	echo "$THUMB_PATH"
715
}
716
717
getsearchtitle() {
718
local CHANID="$1"
719
local STARTTIME="$2"
720
local TI
721
local ST
722
local SEARCHTITLE
723
	[ -n "$CHANID" ] || return 1
724
	if [ -n "$TITLE" -a -n "$SUBTITLE" ]
725
	then
726
		SEARCHTITLE="${TITLE}:${SUBTITLE}"
727
	elif [ -n "$TITLE" ]
728
	then
729
		SEARCHTITLE="${TITLE}"
730
	fi
731
	echo $SEARCHTITLE
732
}
733
734
lookupinetref() {
735
# : is used to separate Title and SubTitle in SEARCHTITLE
736
local SEARCHTITLE="$1"
737
local CHANID="$2"
738
local STARTTIME="$3"
739
local IMDBCMD
740
local IMDBRES
741
local IMDBSTR=""
742
# INETREF will be 00000000 if not found
743
local INETREF=00000000
744
local SERIES
745
local EPISODE
746
local YEAR
747
local TMP
748
	{
749
        IMDBCMD=$(getsetting MovieListCommandLine)
750
	# This is dependent on imdb.pl and will not work with any MovieListCommandLine due to use of s=ep option.
751
	set - $IMDBCMD
752
	IMDBCMD="$1 $2"
753
        IMDBRES=$($IMDBCMD "$SEARCHTITLE")
754
        if [ -n "$IMDBRES" -a $(echo "$IMDBRES" | wc -l) -eq 1 ]
755
        then
756
		IMDBSTR="$IMDBRES"
757
	elif [ -n "$CHANID" ]
758
	then
759
		YEAR=$(getyear $CHANID $STARTTIME)
760
		if [ "$YEAR" -gt 1800 ]
761
		then
762
			for C in 0 1 -1
763
			do
764
				TMP=$(echo "$IMDBRES" | grep $(( $YEAR + $C )))
765
				[ -n "$TMP" -a $(echo "$TMP" | wc -l) -eq 1 ] && IMDBSTR="$TMP" && break
766
			done
767
		fi
768
        fi
769
	if [ -n "$IMDBSTR" ]
770
	then
771
                INETREF=$(echo "$IMDBSTR" | awk -F'[^0-9]' '{print $1}')
772
                echo $INETREF | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*$' >/dev/null 2>&1 || INETREF=00000000
773
	fi
774
        if [ "$INETREF" -eq 00000000 ]
775
        then
776
		# Try looking for episode
777
                OLDIFS="$IFS"; IFS=":"; set - $SEARCHTITLE; IFS="$OLDIFS"
778
		SERIES="$1" ; EPISODE="$2"
779
		if [ -n "$SERIES" -a -n "$EPISODE" ]
780
		then
781
			# option s=ep is for episode lookup
782
			IMDBSTR=$($IMDBCMD s=ep "$EPISODE")
783
			if which agrep >/dev/null 2>&1
784
			then
785
				IMDBSTR=$(echo "$IMDBSTR" | agrep -i -s -2 "$SERIES" | sort -n | head -1 | cut -d':' -f2-)
786
			else
787
				IMDBSTR=$(echo "$IMDBSTR" | grep -i "$SERIES")
788
			fi
789
			if [ $(echo "$IMDBSTR" | wc -l) -eq 1 ]
790
			then
791
				INETREF=$(echo "$IMDBSTR" | awk -F'[^0-9]' '{print $1}')
792
				echo $INETREF | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*$' >/dev/null 2>&1 || INETREF=00000000
793
			fi
794
		fi
795
        fi
796
	scriptlog DEBUG "inetref $INETREF"
797
	} >/dev/null 2>&1
798
        echo $INETREF
799
}
800
801
getseriesepisode() {
802
local CHANID="$1"
803
local STARTTIME="$2"
804
local INETREF="$3"
805
local DATA
806
local SE
807
	[ -n "$CHANID" ] || return 1
808
809
	if [ -n "$META_EPISODE" ]
810
	then
811
		SE=$(echo "$META_EPISODE" | awk "{ printf(\"${EPISODE_FORMAT}\", \$1) }")
812
		[ -n "$META_SEASON" ] && SE=$(echo "|$SE|$META_SEASON|" | awk -F"|" "{ printf(\"${SEASON_FORMAT}\", \$2, \$3) }")
813
	else	
814
		# STARTTIME is not always the same in both tables for matching programs. ???
815
		DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
816
		select syndicatedepisodenumber from recorded a,recordedprogram b
817
		where a.chanid = $CHANID and a.starttime = "$STARTTIME" and a.chanid = b.chanid
818
		and a.title = b.title and a.subtitle = b.subtitle;
819
		EOF
820
		)
821
		DATA=$(echo "$DATA" | awk -F '[SE]' "/S/ { printf(\"${SEASON_FORMAT}\", sprintf(\"${EPISODE_FORMAT}\", \$2), \$3) }")
822
		if echo "$DATA" | egrep -q "${EPISODE_RE}"
823
		then
824
			SE="$DATA"
825
		elif [ $INETREF -gt 0 ]
826
		then
827
			# Lets try passing imdb page
828
			wget -o /dev/null -O "${FIFODIR}/${INETREF}.html" "http://www.imdb.com/title/tt${INETREF}/"
829
			SE=$(awk "/Season.*Episode/ {
830
			a=match(\$0,/Season ([0-9]+)/,s);b=match(\$0,/Episode ([0-9]+)/,e);
831
			if(a>0 && b>0) {
832
				printf(\"${SEASON_FORMAT}\", sprintf(\"${EPISODE_FORMAT}\", e[1]), s[1]);exit}
833
			}" "${FIFODIR}/${INETREF}.html")
834
		fi
835
	fi
836
	echo "$SE" | egrep "$EPISODE_RE"
837
}
838
839
createfiletitleSEsubtitle() {
840
local CHANID="$1"
841
local STARTTIME="$2"
842
local SE="$3"
843
local DATA
844
local T
845
local S
846
	FILE="$TITLE"
847
	[ -n "$META_ARTIST" ] && FILE="${META_ARTIST}${SEP}${FILE}"
848
	[ -n "$SE" ] && FILE=$(echo "|$FILE|$SE|" | awk -F"|" "{ printf(\"${TITLE_FORMAT}\", \$2, \$3 ) }")
849
	[ -z "$SE" -a -n "$SUBTITLE" ] && FILE="${FILE}${SEP}${SUBTITLE}" 
850
	[ -n "$SE" -a -n "$SUBTITLE" ] && FILE="${FILE}${SUBTITLE}" 
851
	[ -n "$META_DATE" ] && FILE=$(echo "|$FILE|$META_DATE" | awk -F"|" "{ printf(\"${DATE_FORMAT}\", \$2, \$3 ) }")
852
	[ -n "$TR" ] && FILE=$(echo $FILE | tr -d '[:cntrl:]' | tr -d '[:punct:]' | tr '[:space:]' "$TR")
853
	echo $FILE
854
}
855
856
is21orless() {
857
	local DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
858
	select subtitle from videometadata limit 1;
859
	EOF
860
	)
861
	echo "$DATA" | egrep 'ERROR.*Unknown column' >/dev/null 2>&1 && return 0 || return 1
862
}
863
864
is24ormore() {
865
	local DATA=$(mythtranscode --audiotrack 2>&1)
866
	echo "$DATA" | grep -q 'Unknown option: --audiotrack' && return 1 || return 0
867
}
868
869
createvideometadata() {
870
local FILENAME="$1"
871
local TITLE="$2"
872
local ASPECT="$3"
873
local CHANID="$4"
874
local STARTTIME="$5"
875
local INETREF="$6"
876
# SE may be null
877
local SE="$7"
878
local DIRECTOR="Unknown"
879
#local PLOT="None"
880
local PLOT="$(getplot $CHANID $STARTTIME)"
881
local MOVIERATING="NR"
882
#local YEAR=1895
883
local YEAR="$(getyear $CHANID $STARTTIME)"
884
local USERRATING=0
885
local RUNTIME=0
886
local COVERFILE="No Cover"
887
local GENRES=""
888
local COUNTRIES=""
889
local CATEGORY=""
890
local CFDIR=$(getsetting "VideoArtworkDir")
891
local TI
892
local ST
893
local IMDBCMD
894
local IMDBSTR
895
local GTYPE
896
local TH
897
local SE
898
local S
899
local E
900
local WHERE
901
local TMP
902
local IDS
903
local VIDID
904
local COUNT
905
	# Title name generation is a mess. Should do something better
906
	if ! is21orless
907
	then
908
		scriptlog INFO "MythTV V0.22 or greater. Not creating MythVideo entry. Use MythVideo menu"
909
		return 0
910
	fi
911
	if hasvideometadata "$FILENAME"
912
	then
913
		scriptlog INFO "$FILENAME already has a videometdata entry."
914
		return 0
915
	fi
916
	# Since I strip special characters in TITLE, use chanid/starttime for metadata title.
917
	if [ -n "$CHANID" ]
918
	then
919
		TI=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
920
		select title from recorded where chanid = $CHANID and starttime = "$STARTTIME";
921
		EOF
922
		)
923
		ST=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
924
		select subtitle from recorded where chanid = $CHANID and starttime = "$STARTTIME";
925
		EOF
926
		)
927
		if [ -n "$TI" -a -n "$SE" -a -n "$ST" ]
928
		then
929
			TITLE="\\\"${TI}\\\" ${SE} ${ST}"
930
		elif [ -n "$TI" -a -n "$ST" ]
931
		then
932
			TITLE="\\\"${TI}\\\" ${ST}"
933
		elif [ -n "$TI" ]
934
		then
935
			TITLE="${TI}"
936
		fi
937
	fi
938
	if [ $INETREF -gt 0 ]
939
	then
940
		IMDBCMD=$(getsetting MovieDataCommandLine)
941
		IMDBSTR=$($IMDBCMD $INETREF | sed -e 's/"/\\"/g')
942
		TMP=$(echo "$IMDBSTR" | grep '^Title' | cut -d':' -f2- | sed -e 's/^ *//')
943
		if [ -n "$TMP" ]
944
		then
945
			# Try and put series and episode number back in. Based on imdb placing quotes around series name. A bit dodgy
946
			if [ -n "$SE" ]
947
			then
948
				TMP=$(echo "$TMP" | awk -v s=${SE} '{
949
				r=match($0,/"(.*)" (.*)/,m)
950
				if(r>0) { print("\\\""m[1]"\\\" "s" "m[2]) }
951
				else { print($0) }
952
				}' | sed -e 's/\\\\"/\\"/g')
953
			fi
954
			TITLE="$TMP"
955
		fi
956
		TMP=$(echo "$IMDBSTR" | grep '^Year' | cut -d':' -f2- | sed -e 's/^ *//')
957
		[ -n "$TMP" ] && YEAR="$TMP"
958
		TMP=$(echo "$IMDBSTR" | grep '^Director' | cut -d':' -f2- | sed -e 's/^ *//')
959
		[ -n "$TMP" ] && DIRECTOR="$TMP"
960
		TMP=$(echo "$IMDBSTR" | grep '^Plot' | cut -d':' -f2- | sed -e 's/^ *//')
961
		[ -n "$TMP" ] && PLOT="$TMP"
962
		TMP=$(echo "$IMDBSTR" | grep '^UserRating' | grep -v '[<>\"]' | cut -d':' -f2- | sed -e 's/^ *//')
963
		[ -n "$TMP" ] && USERRATING="$TMP"
964
		TMP=$(echo "$IMDBSTR" | grep '^MovieRating' | cut -d':' -f2- | sed -e 's/^ *//')
965
		[ -n "$TMP" ] && MOVIERATING="$TMP"
966
		TMP=$(echo "$IMDBSTR" | grep '^Runtime' | cut -d':' -f2- | sed -e 's/^ *//')
967
		[ -n "$TMP" ] && RUNTIME="$TMP"
968
		IMDBCMD=$(getsetting MoviePosterCommandLine)
969
		IMDBCOVER=$($IMDBCMD $INETREF)
970
		if [ -n "$IMDBCOVER" ]
971
		then
972
			GTYPE=$(echo $IMDBCOVER | sed -e 's/.*\(\....\)/\1/')
973
			wget -o /dev/null -O "${CFDIR}/${INETREF}${GTYPE}" $IMDBCOVER 
974
			[ -f "${CFDIR}/${INETREF}${GTYPE}" ] && COVERFILE="${CFDIR}/${INETREF}${GTYPE}"
975
		fi
976
		TMP=$(echo "$IMDBSTR" | grep '^Genres' | cut -d':' -f2- | sed -e 's/^ *//')
977
		[ -n "$TMP" ] && GENRES="$TMP"
978
		TMP=$(echo "$IMDBSTR" | grep '^Countries' | cut -d':' -f2- | sed -e 's/^ *//')
979
		[ -n "$TMP" ] && COUNTRIES="$TMP"
980
		TMP=$(echo "$IMDBSTR" | grep '^Cast' | cut -d':' -f2- | sed -e 's/^ *//')
981
		[ -n "$TMP" ] && CASTMEMBERS="$TMP"
982
	fi
983
	if ! [ -f "$COVERFILE" ]
984
	then
985
		scriptlog INFO "Creating cover file."
986
		TH=$(createvideocover "$CFDIR" "$FILENAME" $ASPECT)
987
		[ -f ${TH} ] && COVERFILE="${TH}"
988
	fi
989
	scriptlog INFO "Creating videometadata entry. Inetref:$INETREF. Title:$TITLE"
990
	if [ "$DEBUGSQL" = "ON" ]
991
	then
992
		cat <<-EOF
993
		insert into videometadata set
994
		title = "$TITLE",
995
		director = "$DIRECTOR",
996
		plot = "$PLOT",
997
		rating = "$MOVIERATING",
998
		inetref = "$INETREF",
999
		year = $YEAR,
1000
		userrating = $USERRATING,
1001
		length = $RUNTIME,
1002
		showlevel = 1,
1003
		filename = "$FILENAME",
1004
		coverfile = "$COVERFILE",
1005
		childid = -1,
1006
		browse = 1,
1007
		playcommand = NULL,
1008
		category = 0;
1009
		EOF
1010
	fi
1011
	mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1012
	insert into videometadata set
1013
	title = "$TITLE",
1014
	director = "$DIRECTOR",
1015
	plot = "$PLOT",
1016
	rating = "$MOVIERATING",
1017
	inetref = "$INETREF",
1018
	year = $YEAR,
1019
	userrating = $USERRATING,
1020
	length = $RUNTIME,
1021
	showlevel = 1,
1022
	filename = "$FILENAME",
1023
	coverfile = "$COVERFILE",
1024
	childid = -1,
1025
	browse = 1,
1026
	playcommand = NULL,
1027
	category = 0;
1028
	EOF
1029
	CATEGORY=$(getcategory "$CHANID" "$STARTTIME")
1030
	if [ -n "$GENRES" -o -n "$COUNTRIES" -o -n "$CASTMEMBERS" -o -n "$CATEGORY" ]
1031
	then
1032
		VIDID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1033
		select intid from videometadata where filename = "$FILENAME";
1034
		EOF
1035
		)
1036
	fi
1037
	if [ -n "$VIDID" ]
1038
	then
1039
		if [ -n "$GENRES" ]
1040
		then
1041
			scriptlog DEBUG "Will check for genres $GENRES"
1042
			OLDIFS="$IFS"; IFS=','; set - $GENRES; IFS="$OLDIFS"
1043
			for GENRE in "$@"
1044
			do
1045
				ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1046
				select intid from videogenre where lcase(genre) = lcase("${GENRE}");
1047
				EOF
1048
				)
1049
				if [ -z "$ID" ]
1050
				then
1051
					[ "$DEBUGSQL" = "ON" ] && echo "insert into videogenre set genre = ${GENRE}"
1052
					mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1053
					insert into videogenre set genre = "${GENRE}";
1054
					EOF
1055
					ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1056
					select intid from videogenre where lcase(genre) = lcase("${GENRE}");
1057
					EOF
1058
					)
1059
				fi
1060
				if [ -n "$ID" ]
1061
				then
1062
					TMP=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1063
					select idvideo from videometadatagenre where idvideo = $VIDID and idgenre = $ID;
1064
					EOF
1065
					)
1066
					if [ -z "$TMP" ]
1067
					then
1068
						[ "$DEBUGSQL" = "ON" ] && echo "insert into videometadatagenre set idvideo = $VIDID, idgenre = $ID - $GENRE"
1069
						mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1070
						insert into videometadatagenre set idvideo = $VIDID, idgenre = $ID;
1071
						EOF
1072
						scriptlog INFO "Adding to genre $GENRE"
1073
					fi
1074
				fi
1075
			done
1076
		fi
1077
1078
		if [ -n "$COUNTRIES" ]
1079
		then
1080
			scriptlog DEBUG "Will check for countries $COUNTRIES"
1081
			OLDIFS="$IFS"; IFS=','; set - $COUNTRIES; IFS="$OLDIFS"
1082
			for COUNTRY in "$@"
1083
			do
1084
				ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1085
				select intid from videocountry where lcase(country) = lcase("${COUNTRY}");
1086
				EOF
1087
				)
1088
				if [ -z "$ID" ]
1089
				then
1090
					[ "$DEBUGSQL" = "ON" ] && echo "insert into videocountry set country = ${COUNTRY}"
1091
					mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1092
					insert into videocountry set country = "${COUNTRY}";
1093
					EOF
1094
					ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1095
					select intid from videocountry where lcase(country) = lcase("${COUNTRY}");
1096
					EOF
1097
					)
1098
				fi
1099
				if [ -n "$ID" ]
1100
				then
1101
					TMP=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1102
					select idvideo from videometadatacountry where idvideo = $VIDID and idcountry = $ID;
1103
					EOF
1104
					)
1105
					if [ -z "$TMP" ]
1106
					then
1107
						[ "$DEBUGSQL" = "ON" ] && echo "insert into videometadatacountry set idvideo = $VIDID, idcountry = $ID - $COUNTRY"
1108
						mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1109
						insert into videometadatacountry set idvideo = $VIDID, idcountry = $ID;
1110
						EOF
1111
						scriptlog INFO "Adding to country $COUNTRY"
1112
					fi
1113
				fi
1114
			done
1115
		fi
1116
1117
		if [ -n "$CASTMEMBERS" ]
1118
		then
1119
			scriptlog DEBUG "Will check for cast $CASTMEMBERS"
1120
			OLDIFS="$IFS"; IFS=","; set - $CASTMEMBERS; IFS="$OLDIFS"
1121
			for CAST in "$@"
1122
			do
1123
				ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1124
				select intid from videocast where lcase(cast) = lcase("${CAST}");
1125
				EOF
1126
				)
1127
				if [ -z "$ID" ]
1128
				then
1129
					[ "$DEBUGSQL" = "ON" ] && echo "insert into videocast set cast = ${CAST}"
1130
					mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1131
					insert into videocast set cast = "${CAST}";
1132
					EOF
1133
					ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1134
					select intid from videocast where lcase(cast) = lcase("${CAST}");
1135
					EOF
1136
					)
1137
				fi
1138
				if [ -n "$ID" ]
1139
				then
1140
					TMP=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1141
					select idvideo from videometadatacast where idvideo = $VIDID and idcast = $ID;
1142
					EOF
1143
					)
1144
					if [ -z "$TMP" ]
1145
					then
1146
						[ "$DEBUGSQL" = "ON" ] && echo "insert into videometadatacast set idvideo = $VIDID, idcast = $ID - $CAST"
1147
						mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1148
						insert into videometadatacast set idvideo = $VIDID, idcast = $ID;
1149
						EOF
1150
						scriptlog INFO "Adding cast member $CAST"
1151
					fi
1152
				fi
1153
			done
1154
		fi
1155
1156
		if [ -n "$CATEGORY" ]
1157
		then
1158
			CATEGORY=$(echo "$CATEGORY" | tr -d ' ')
1159
			OLDIFS="$IFS"; IFS='/'; set - $CATEGORY; IFS="$OLDIFS"
1160
			for CAT in "$@"
1161
			do
1162
				# Use mappings
1163
				[ -n "${mythcat[$CAT]}" ] && CAT=${mythcat[$CAT]}
1164
				[ "$DEBUGSQL" = "ON" ] && echo "select intid from videocategory where lcase(category) = lcase(${CAT})"
1165
				ID=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1166
				select intid from videocategory where lcase(category) = lcase("${CAT}"); 
1167
				EOF
1168
				)
1169
				if [ -n "$ID" ]
1170
				then
1171
					[ "$DEBUGSQL" = "ON" ] && echo "update videometadata set category = $ID where intid = $VIDID"
1172
					mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1173
					update videometadata set category = $ID where intid = $VIDID;
1174
					EOF
1175
					scriptlog INFO "Added to category $CAT"
1176
					break # only 1 category
1177
				else
1178
					scriptlog INFO "Category $CAT does not exist"
1179
				fi
1180
			done
1181
		fi
1182
	fi
1183
	return 0
1184
}
1185
1186
hasvideometadata() {
1187
local FILENAME="$1"
1188
local DATA
1189
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1190
	select intid from videometadata where filename = "$FILENAME";
1191
	EOF
1192
	)
1193
	echo $DATA | grep '^[0-9][0-9][0-9]*$' >/dev/null 2>&1 && return 0 || return 1
1194
}
1195
1196
deleterecording() {
1197
local CHANID="$1"
1198
local STARTTIME="$2"
1199
	[ -n "$CHANID" ] || return 1
1200
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1201
	update recorded set recgroup = "Deleted", autoexpire = 999 where chanid = $CHANID and starttime = "$STARTTIME";
1202
	EOF
1203
}
1204
1205
insertmythlogentry() {
1206
local PRIORITY="$1"
1207
local LEVEL="$2"
1208
local PID="$3"
1209
local DETAILS="$(echo $4 | tr -d '[:cntrl:]' | tr -d '[\\\"]')"
1210
local DATETIME=$(date '+%Y%m%d%H%M%S')
1211
local HOST=$(hostname)
1212
	mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1213
	insert into mythlog set
1214
	module = "mythnuv2mkv.sh",
1215
	priority = $PRIORITY,
1216
	acknowledged = 0,
1217
	logdate = $DATETIME,
1218
	host = "$HOST",
1219
	message = "mythnuv2mkv.sh [$PID] $LEVEL",
1220
	details = "$DETAILS";
1221
	EOF
1222
}
1223
1224
getjobqueuecmds() {
1225
local JOBID="$1"
1226
local DATA
1227
local JQCMDSTR[0]="RUN"
1228
local JQCMDSTR[1]="PAUSE"
1229
local JQCMDSTR[2]="RESUME"
1230
local JQCMDSTR[4]="STOP"
1231
local JQCMDSTR[8]="RESTART"
1232
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1233
	select cmds from jobqueue where id = $JOBID;
1234
	EOF
1235
	)
1236
	echo ${JQCMDSTR[$DATA]}
1237
}
1238
1239
setjobqueuecmds() {
1240
local JOBID="$1"
1241
local CMDSSTR="$2"
1242
local CMDS
1243
	if echo "$CMDSSTR" | egrep '^[0-9]+$' >/dev/null 2>&1
1244
	then
1245
		CMDS=$CMDSSTR
1246
	elif [ "$CMDSSTR" = "RUN" ]
1247
	then
1248
		CMDS=0
1249
	fi
1250
	if [ -n "$CMDS" ]
1251
	then
1252
		mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1253
		update jobqueue set cmds = $CMDS where id = $JOBID;
1254
		EOF
1255
	else
1256
		scriptlog ERROR "Invalid Job Queue Command."
1257
	fi
1258
}
1259
1260
getjobqueuestatus() {
1261
local JOBID="$1"
1262
local DATA
1263
local JQSTATUSSTR[0]="UNKNOWN"
1264
local JQSTATUSSTR[1]="QUEUED"
1265
local JQSTATUSSTR[2]="PENDING"
1266
local JQSTATUSSTR[3]="STARTING"
1267
local JQSTATUSSTR[4]="RUNNING"
1268
local JQSTATUSSTR[5]="STOPPING"
1269
local JQSTATUSSTR[6]="PAUSED"
1270
local JQSTATUSSTR[7]="RETRY"
1271
local JQSTATUSSTR[8]="ERRORING"
1272
local JQSTATUSSTR[9]="ABORTING"
1273
local JQSTATUSSTR[256]="DONE"
1274
local JQSTATUSSTR[272]="FINISHED"
1275
local JQSTATUSSTR[288]="ABORTED"
1276
local JQSTATUSSTR[304]="ERRORED"
1277
local JQSTATUSSTR[320]="CANCELLED"
1278
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1279
	select status from jobqueue where id = $JOBID;
1280
	EOF
1281
	)
1282
	echo ${JQSTATUSSTR[$DATA]}
1283
}
1284
1285
setjobqueuestatus() {
1286
local JOBID="$1"
1287
local STATUSSTR="$2"
1288
local STATUS
1289
	if echo "$STATUSSTR" | egrep '^[0-9]+$' >/dev/null 2>&1
1290
	then
1291
		STATUS=$STATUSSTR
1292
	elif [ "$STATUSSTR" = "RUNNING" ]
1293
	then
1294
		STATUS=4
1295
	elif [ "$STATUSSTR" = "PAUSED" ]
1296
	then
1297
		STATUS=6
1298
	elif [ "$STATUSSTR" = "ABORTING" ]
1299
	then
1300
		STATUS=9
1301
	elif [ "$STATUSSTR" = "FINISHED" ]
1302
	then
1303
		STATUS=272
1304
	elif [ "$STATUSSTR" = "ERRORED" ]
1305
	then
1306
		STATUS=304
1307
	fi
1308
	if [ -n "$STATUS" ]
1309
	then
1310
		mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1311
		update jobqueue set status = $STATUS where id = $JOBID;
1312
		EOF
1313
	else
1314
		scriptlog ERROR "Invalid Job Queue Status."
1315
	fi
1316
}
1317
1318
getjobqueuecomment() {
1319
local JOBID="$1"
1320
local COMMENT="$2"
1321
	mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1322
	select comment from jobqueue where id = $JOBID;
1323
	EOF
1324
}
1325
1326
setjobqueuecomment() {
1327
local JOBID="$1"
1328
local COMMENT="$2"
1329
	mysql --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1330
	update jobqueue set comment = "$COMMENT" where id = $JOBID;
1331
	EOF
1332
}
1333
1334
# My channelprofiles table for setting aspect at channel level.
1335
# See http://web.aanet.com.au/auric/?q=node/1
1336
# You probably don't have it.
1337
getchannelaspect() {
1338
local CHANID=$1
1339
local DATA
1340
	{
1341
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1342
	select aspectratio from channelprofiles
1343
		where channum = (select channum from channel where chanid = $CHANID)
1344
		and sourceid = (select sourceid from channel where chanid = $CHANID);
1345
	EOF
1346
	)
1347
	case $DATA in
1348
		16:9|4:3) true ;;
1349
		'') DATA=$DEFAULTMPEG2ASPECT ;;
1350
		*) DATA=NA ;;
1351
	esac
1352
	} >/dev/null 2>&1
1353
	echo $DATA
1354
}
1355
1356
# aspect ratio of the V4L or MPEG capture card associated with CHANID
1357
# No good for any other type of card. e.g. DVB.
1358
querycardaspect() {
1359
local CHANID=$1
1360
local DATA
1361
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
1362
	select value from codecparams where name = 'mpeg2aspectratio'
1363
	and profile = (select id from recordingprofiles where name = 'default'
1364
		and profilegroup = (select id from profilegroups
1365
			where cardtype = (select cardtype from capturecard
1366
				where cardid = (select cardid from cardinput
1367
					where sourceid = (select sourceid from channel
1368
						where chanid = $CHANID)
1369
					)
1370
				)
1371
			)
1372
		);
1373
	EOF
1374
	)
1375
	[ "$DATA" != "4:3" -a "$DATA" != "16:9" ] && DATA="NA"
1376
	echo $DATA
1377
}
1378
1379
getaviinfomidentify() {
1380
local FILE="$1"
1381
local ATRACK="$2"
1382
shift 2 
1383
local PROPS="$@"
1384
local MPOP
1385
local TMP
1386
local p
1387
local RES
1388
local ASPECTFOUNDIN
1389
local width=1			; infokey[1]="ID_VIDEO_WIDTH"
1390
local height=2			; infokey[2]="ID_VIDEO_HEIGHT"
1391
local fps=3			; infokey[3]="ID_VIDEO_FPS"
1392
local audio_sample_rate=4	; infokey[4]="ID_AUDIO_RATE"
1393
local audio_channels=5		; infokey[5]="ID_AUDIO_NCH"
1394
local aspect=6			; infokey[6]="ID_VIDEO_ASPECT"
1395
local length=7			; infokey[7]="ID_LENGTH"
1396
local video_format=8		; infokey[8]="ID_VIDEO_FORMAT"
1397
local audio_format=9		; infokey[9]="ID_AUDIO_CODEC"
1398
	ATRACK_PID=$(mplayer -really-quiet -nojoystick -nolirc -nomouseinput -vo null -ao null -frames 0 -identify "$FILE" 2>/dev/null | \
1399
		awk -F"=" "/ID_AUDIO_ID=([0-9]+)/ { if ( x++ == $ATRACK ) print \$2 }")
1400
	MPOP=$(mplayer -aid ${ATRACK_PID} -really-quiet -nojoystick -nolirc -nomouseinput -vo null -ao null -frames 0 -identify "$FILE" 2>/dev/null)
1401
	for p in $PROPS
1402
	do
1403
		[ -n "${infokey[$p]}" ] && p=${infokey[$p]}
1404
		case $p in
1405
			"scan_type")
1406
				TMP="NA"
1407
			;;
1408
			"finfo")
1409
				TMP="NA"
1410
			;;
1411
			"audio_bitrate")
1412
				TMP="NA"
1413
			;;
1414
			"audio_resolution")
1415
				TMP="NA"
1416
			;;
1417
			"audio_language")
1418
				TMP="NA"
1419
			;;
1420
			"ID_VIDEO_ASPECT")
1421
				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"}')"
1422
				[ "$TMP" != "4:3" -a "$TMP" != "16:9" ] && TMP="NA"
1423
				ASPECTFOUNDIN="File"
1424
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" -a -n "$CHANID" ]
1425
				then
1426
					TMP=$(getchannelaspect $CHANID)
1427
					ASPECTFOUNDIN="Channel"
1428
				fi
1429
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" -a -n "$CHANID" ]
1430
				then
1431
					TMP=$(querycardaspect $CHANID)
1432
					ASPECTFOUNDIN="Card"
1433
				fi
1434
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" ]
1435
				then
1436
					TMP=$DEFAULTMPEG2ASPECT
1437
					ASPECTFOUNDIN="Default"
1438
				fi
1439
				TMP="$TMP,$ASPECTFOUNDIN"
1440
			;;
1441
			"ID_VIDEO_HEIGHT")
1442
				TMP="$(echo "$MPOP" | grep $p | tail -1 | cut -d'=' -f2)"
1443
				[ "$TMP" = "1080" ] && TMP="1088" # HD FIX
1444
			;;
1445
			"ID_VIDEO_FORMAT")
1446
				TMP="$(echo "$MPOP" | grep $p | tail -1 | cut -d'=' -f2)"
1447
				case "$TMP" in
1448
					"0x10000002") TMP="MPEG" ;;
1449
					"avc1") TMP="AVC" ;;
1450
					"MPEG-4 Visual") TMP="MPEG4" ;;
1451
					"FMP4") TMP="MPEG4" ;;
1452
					"DX50") TMP="DIVX" ;;
1453
					"H264") TMP="H264" ;;
1454
				esac
1455
			;;
1456
			*)
1457
				TMP="$(echo "$MPOP" | grep $p | tail -1 | cut -d'=' -f2)"
1458
			;;
1459
		esac
1460
		[ -z "$RES" ] && RES="$TMP" || RES="${RES}:${TMP}"
1461
	done
1462
	echo "$RES"
1463
}
1464
1465
getaviinfomediainfo() {
1466
local FILE="$1"
1467
local ATRACK="$2"
1468
shift
1469
local PROPS="$@"
1470
local TMP
1471
local p
1472
local RES
1473
local ASPECTFOUNDIN
1474
	for p in $PROPS
1475
	do
1476
		TMP=""
1477
		case "$p" in
1478
			"aspect")
1479
				TMP=$(mediainfo --Inform="Video;%DisplayAspectRatio/String%" "$FILE")
1480
				if [ "$TMP" = "4:3" -o "$TMP" = "4/3" ]
1481
				then
1482
					ASPECTFOUNDIN="File"
1483
				elif [ "$TMP" = "16:9" -o "$TMP" = "16/9" ]
1484
				then
1485
					ASPECTFOUNDIN="File"
1486
				else
1487
					TMP="NA"
1488
				fi
1489
1490
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" -a -n "$CHANID" ]
1491
				then
1492
					TMP=$(getchannelaspect $CHANID)
1493
					ASPECTFOUNDIN="Channel"
1494
				fi
1495
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" -a -n "$CHANID" ]
1496
				then
1497
					TMP=$(querycardaspect $CHANID)
1498
					ASPECTFOUNDIN="Card"
1499
				fi
1500
				if [ "$TMP" = "NA" -a ${FILE##*.} = "mpg" ]
1501
				then
1502
					TMP=$DEFAULTMPEG2ASPECT
1503
					ASPECTFOUNDIN="Default"
1504
				fi
1505
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1506
				TMP="$TMP,$ASPECTFOUNDIN"
1507
			;;
1508
			"height")
1509
				TMP=$(mediainfo --Inform="Video;%Height%" "$FILE")
1510
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1511
				[ "$TMP" = "1080" ] && TMP="1088" # HD FIX
1512
			;;
1513
			"audio_sample_rate")
1514
				TMP=$(mediainfo --Inform="Audio;%SamplingRate/String%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 * 1000 }")
1515
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1516
			;;
1517
			"Duration")
1518
				TMP=$(mediainfo --Inform="Video;%Duration%" "$FILE")
1519
			;;
1520
			"video_format")
1521
				TMP=$(getaviinfomidentify "$FILE" video_format)
1522
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1523
			;;
1524
			"width")
1525
				TMP=$(mediainfo --Inform="Video;%Width%" "$FILE")
1526
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1527
			;;
1528
			"fps")
1529
				TMP=$(mediainfo --Inform="Video;%FrameRate%" "$FILE")
1530
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1531
			;;
1532
			"audio_channels")
1533
				TMP=$(mediainfo --Inform="Audio;%Channel(s)/String%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 }")
1534
				[ -z "$TMP" ] && TMP=$(getaviinfomidentify "$FILE" $ATRACK "$p")
1535
			;;
1536
			"audio_bitrate")
1537
				TMP=$(mediainfo --Inform="Audio;%BitRate/String%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 }")
1538
				[ -z "$TMP" ] && TMP="NA"
1539
			;;
1540
			"audio_resolution")
1541
				TMP=$(mediainfo --Inform="Audio;%Resolution/String%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 }")
1542
				[ -z "$TMP" ] && TMP="NA"
1543
			;;
1544
			"scan_type")
1545
				TMP=$(mediainfo --Inform="Video;%ScanType%" "$FILE")
1546
				[ "$TMP" = "MBAFF" ] && TMP="Interlaced"
1547
				[ -z "$TMP" ] && TMP="NA"
1548
			;;
1549
			"audio_language")
1550
				TMP=$(mediainfo --Inform="Audio;%Language/String3%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 }")
1551
				[ -z "$TMP" ] && TMP="NA"
1552
			;;
1553
			"audio_format")
1554
				TMP=$(mediainfo --Inform="Audio;%Format%\n" "$FILE" | awk "{ if ( x++ == $ATRACK ) print \$1 }")
1555
				[ -z "$TMP" ] && TMP="NA"
1556
			;;
1557
		esac
1558
		[ -z "$RES" ] && RES="$TMP" || RES="${RES}:${TMP}"
1559
	done
1560
	echo "$RES"
1561
}
1562
1563
getnuvinfo() {
1564
export NUVINFOFILE="$1"
1565
shift
1566
export NUVINFOPROPS="$@"
1567
	PROPS=$(sed -n '/^#STARTNUVINFO$/,/#ENDNUVINFO/p' $CMD | perl)
1568
	echo "$PROPS"
1569
}
1570
1571
getvidinfo() {
1572
local FILE="$1"
1573
local ATRACK="$2"
1574
shift 2
1575
local PROPS="$@"
1576
local RES
1577
	if echo "$FILE" | grep '\.nuv' >/dev/null 2>&1
1578
	then	
1579
		RES=$(getnuvinfo "$FILE" $PROPS)
1580
	else
1581
		if [ "$USEMEDIAINFO" = "TRUE" ] && which mediainfo >/dev/null 2>&1
1582
		then
1583
			RES=$(getaviinfomediainfo "$FILE" $ATRACK $PROPS)
1584
		else
1585
			RES=$(getaviinfomidentify "$FILE" $ATRACK $PROPS)
1586
		fi
1587
	fi
1588
	echo "$RES"
1589
}
1590
1591
getaspect() {
1592
local FILE="$1"
1593
local ASPECT="NA"
1594
	ASPECT=$(getvidinfo "$FILE" 0 aspect)
1595
	ASPECT=$(echo $ASPECT | sed -e 's/\./:/')
1596
	echo "$ASPECT" | grep ',' >/dev/null 2>&1 || ASPECT="$ASPECT,File"
1597
	echo "$ASPECT"
1598
}
1599
1600
getlengthffmpeg() {
1601
FILE="$1"
1602
local LENGTH=""
1603
	LENGTH=$(ffmpeg -i "$FILE" 2>&1 | awk -F'[:.]' '/Duration: / {print $2 * 3600 + $3 * 60 + $4}')
1604
	echo "$LENGTH" | grep '^[0-9][0-9]*$'
1605
}
1606
1607
getlength() {
1608
FILE="$1"
1609
local LENGTH=""
1610
	LENGTH=$(getaviinfomidentify "$FILE" 0 length)
1611
	if [ -z "$LENGTH" -o "$LENGTH" -lt 1 ]
1612
	then
1613
		scriptlog DEBUG "getaviinfomidentify failed length $LENGTH"
1614
		LENGTH=$(getlengthffmpeg "$FILE")
1615
		if [ -z "$LENGTH" -a "$LENGTH" -lt 0 ]
1616
		then
1617
			scriptlog DEBUG "getlengthffmpeg failed length $LENGTH"
1618
			return 1
1619
		fi
1620
	fi
1621
	echo $LENGTH
1622
}
1623
1624
# save value $2 in variable $1, optionally saving the original value into \$SAVED$1
1625
setsave() {
1626
	local VARNAME=$1
1627
	local SAVED="SAVED${VARNAME}"
1628
	local VALUE=$2
1629
	local SAVE=$3
1630
	scriptlog DEBUG SetSaving "$VARNAME=$VALUE (old: ${!VARNAME}, save: $SAVE)"
1631
	# only save once, and only if changed
1632
	[ -n "$SAVE" -a -z "${!SAVED}" -a "${!VARNAME}" != "$VALUE" ] && eval "$SAVED=\"${!VARNAME}\""
1633
	# forget old saved value
1634
	[ -z "$SAVE" ] && eval "$SAVED="
1635
	eval "${VARNAME}=\"${VALUE}\""
1636
}
1637
1638
# recall saved value of variable $1, if available
1639
recall() {
1640
	if [ -z "$@" ]
1641
	then
1642
		for VARNAME in $RECALL
1643
		do
1644
			recall $VARNAME
1645
		done
1646
		for VARNAME in $CLEAN
1647
		do
1648
			eval "$VARNAME="
1649
		done
1650
	else
1651
		local VARNAME=$1
1652
		local SAVED="SAVED${VARNAME}"
1653
		if [ -n "${!SAVED}" ]
1654
		then
1655
			scriptlog DEBUG "Recalling $VARNAME from ${!VARNAME}, saved ${!SAVED}"
1656
			eval "${VARNAME}=\"${!SAVED}\""
1657
			eval "${SAVED}="
1658
		fi
1659
	fi
1660
}
1661
1662
setaspect() {
1663
	setsave ASPECTINLINE "$1" "$2"
1664
}
1665
1666
setdenoise() {
1667
	setsave DENOISE "$(echo $1 | tr '[a-z]' '[A-Z]')" "$2"
1668
	if echo "$DENOISE" | egrep -i 'ON|YES' >/dev/null 2>&1
1669
	then
1670
		setsave POSTVIDFILTERS "${POSTVIDFILTERS}${DENOISEFILTER}," "$2"
1671
		scriptlog INFO "Denoise filter added."
1672
	else
1673
		setsave POSTVIDFILTERS "$(echo ${POSTVIDFILTERS} | sed -e 's/'${DENOISEFILTER}',//')" "$2"
1674
		scriptlog INFO "Denoise filter removed."
1675
	fi
1676
}
1677
1678
setdeblock() {
1679
	setsave DEBLOCK "$(echo $1 | tr '[a-z]' '[A-Z]')" "$2"
1680
	if echo "$DEBLOCK" | egrep -i 'ON|YES' >/dev/null 2>&1
1681
	then
1682
		setsave POSTVIDFILTERS "${POSTVIDFILTERS}${DEBLOCKFILTER}," "$2"
1683
		scriptlog INFO "Deblock filter added."
1684
	else
1685
		setsave POSTVIDFILTERS "$(echo ${POSTVIDFILTERS} | sed -e 's/'${DEBLOCKFILTER}',//')" "$2"
1686
		scriptlog INFO "Deblock filter removed."
1687
	fi
1688
}
1689
1690
setdeinterlace() {
1691
	setsave DEINTERLACE "$(echo $1 | tr '[a-z]' '[A-Z]')" "$2"
1692
	if echo "$DEINTERLACE" | egrep -i 'ON|YES' >/dev/null 2>&1
1693
	then
1694
		scriptlog INFO "Deinterlace filter made available."
1695
	else
1696
		scriptlog INFO "Deinterlace filter made unavailable."
1697
	fi
1698
}
1699
1700
setinvtelecine() {
1701
	setsave INVTELECINE "$(echo "$1" | tr '[a-z]' '[A-Z]')" "$2"
1702
	if echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1
1703
	then
1704
		scriptlog INFO "Invtelecine filter made available."
1705
	else
1706
		scriptlog INFO "Invtelecine filter made unavailable."
1707
	fi
1708
}
1709
1710
setcrop() {
1711
	setsave CROP $(echo "$1" | tr '[a-z]' '[A-Z]') "$2"
1712
	if echo "$CROP" | egrep '[0-9]+' >/dev/null 2>&1
1713
	then
1714
		setsave CROPSIZE "$CROP" "$2"
1715
		setsave CROP "ON" "$2"
1716
		scriptlog INFO "Cropping $CROPSIZE pixels from each side"
1717
		[ $(( ($CROPSIZE*2) % 16 )) -ne 0 ] && scriptlog WARN "WARNING Crop sizes NOT a multiple of 16. This is bad"
1718
	elif [ "$CROP" = "ON" ]
1719
	then
1720
		scriptlog INFO "Cropping $CROPSIZE pixels from each side"
1721
	else
1722
		scriptlog INFO "Crop set $CROP."
1723
	fi
1724
}
1725
1726
setdeleterec() {
1727
	setsave DELETEREC "$(echo "$1" | tr '[a-z]' '[A-Z]')" "$2"
1728
	scriptlog INFO "Delete Recording set to $DELETEREC."
1729
}
1730
1731
setchapterduration() {
1732
	setsave CHAPTERDURATION "$1" "$2"
1733
	scriptlog INFO "Chapter Duration set to $CHAPTERDURATION."
1734
}
1735
1736
setchapterfile() {
1737
	setsave CHAPTERFILE "$1" "$2"
1738
	if [ -f "$CHAPTERFILE" ]
1739
	then
1740
		scriptlog INFO "Chapter File set to $CHAPTERFILE."
1741
	else
1742
		setsave CHAPTERFILE "" "$2"
1743
		scriptlog ERROR "Chapter File $CHAPTERFILE not found."
1744
	fi
1745
}
1746
1747
setcopydir() {
1748
	setsave COPYDIR "$1" "$2"
1749
	if [ ! -d "$COPYDIR" -o ! -w "$COPYDIR" ] && ! mkdir -p "$COPYDIR" 
1750
	then
1751
		scriptlog ERROR "$COPYDIR does not exist and cannot be created or is not writable. Continuing but result will be left in source directory unless $COPYDIR is created before job completes."
1752
		return 1
1753
	else 
1754
		scriptlog INFO "Video will be located in $COPYDIR."
1755
		return 0
1756
	fi	
1757
}
1758
1759
setcontype() {
1760
	local TMP=$(echo "$1" | tr '[A-Z]' '[a-z]')
1761
	local SAVE=$2
1762
	local OLDIFS="$IFS"; IFS=","; set - $TMP; IFS="$OLDIFS"
1763
	local TMP1="$1" ; local TMP2="$2"
1764
	if [ "$TMP1" = "mp4" ]
1765
	then
1766
		if [ -n "$CHANID" -a -z "$COPYDIR" ]
1767
		then
1768
			setsave CONTYPE "avi" "$SAVE"
1769
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1770
			scriptlog ERROR "Changed to $TMP1 failed. mp4 not supported in MythRecord."
1771
		elif ! chkreqs "$MP4REQPROGS" "$MP4REQLIBS"
1772
		then
1773
			scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
1774
			exit $FINALEXIT
1775
		else
1776
			setsave CONTYPE "mp4" "$SAVE"
1777
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1778
			scriptlog INFO "Changed to $CONTYPE."
1779
		fi
1780
	elif [ "$TMP1" = "mov" ]
1781
	then
1782
		if [ -n "$CHANID" -a -z "$COPYDIR" ]
1783
		then
1784
			setsave CONTYPE "avi" "$SAVE"
1785
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1786
			scriptlog ERROR "Changed to $TMP1 failed. mov not supported in MythRecord."
1787
		elif ! chkreqs "$MP4REQPROGS" "$MP4REQLIBS"
1788
		then
1789
			scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
1790
			exit $FINALEXIT
1791
		else
1792
			setsave CONTYPE "mp4" "$SAVE"
1793
			setsave QUICKTIME_MP4 "YES" "$SAVE"
1794
			scriptlog INFO "Changed to $CONTYPE (mov)."
1795
		fi
1796
	elif [ "$TMP1" = "mkv" ]
1797
	then
1798
		if [ -n "$CHANID" -a -z "$COPYDIR" ]
1799
		then
1800
			setsave CONTYPE "avi" "$SAVE"
1801
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1802
			scriptlog ERROR "Changed to $TMP1 failed. mkv not supported in MythRecord."
1803
		elif ! chkreqs "$MKVREQPROGS" "$MKVREQLIBS"
1804
		then
1805
			scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
1806
			exit $FINALEXIT
1807
		else
1808
			setsave CONTYPE "mkv" "$SAVE"
1809
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1810
			[ "$TMP2" = "ogg" ] && setsave MKVAUD "ogg" "$SAVE"
1811
			[ "$TMP2" = "acc" ] && setsave MKVAUD "acc" "$SAVE"
1812
			scriptlog INFO "Changed to ${CONTYPE},${MKVAUD}."
1813
		fi
1814
	elif [ "$TMP1" = "avi" ]
1815
	then
1816
		if ! chkreqs "$AVIREQPROGS" "$AVIREQLIBS"
1817
		then
1818
			scriptlog ERROR "Changed to $TMP1 failed. Missing Requirements."
1819
			exit $FINALEXIT
1820
		else
1821
			setsave CONTYPE "avi" "$SAVE"
1822
			setsave QUICKTIME_MP4 "NO" "$SAVE"
1823
			[ "$TMP2" = "xvid" ] && setsave AVIVID "xvid" "$SAVE"
1824
			[ "$TMP2" = "lavc" ] && setsave AVIVID "lavc" "$SAVE"
1825
			[ "$TMP2" = "divx" ] && setsave AVIVID "lavc" "$SAVE"
1826
			scriptlog INFO "Changed to ${CONTYPE},${AVIVID}."
1827
		fi
1828
	else
1829
		scriptlog ERROR "Changed to $TMP1 failed. Invalid contype."
1830
	fi
1831
}
1832
1833
setpass() {
1834
	TMP=$(echo "$1" | tr '[A-Z]' '[a-z]')
1835
	if [ "$TMP" = "one" -o "$TMP" = "1" ]
1836
	then
1837
		scriptlog INFO "Changed to $TMP pass."
1838
		setsave PASS "one" "$2"
1839
	elif [ "$TMP" = "two" -o "$TMP" = "2" ]
1840
	then
1841
		scriptlog INFO "Changed to $TMP pass."
1842
		setsave PASS "two" "$2"
1843
	else
1844
		scriptlog ERROR "Changed to $TMP failed. Invalid value for pass."
1845
	fi
1846
}
1847
1848
setquality() {
1849
	QLEVEL=$1
1850
	SAVE=$2
1851
	if echo "$QLEVEL" | grep -i "high" >/dev/null 2>&1
1852
	then
1853
		setsave SCALE43 $HIGH_SCALE43 "$SAVE"
1854
		setsave SCALE169 $HIGH_SCALE169 "$SAVE"
1855
		setsave LAVC_CQ $HIGH_LAVC_CQ "$SAVE"
1856
		setsave LAVC_OPTS $HIGH_LAVC_OPTS "$SAVE"
1857
		setsave XVID_CQ $HIGH_XVID_CQ "$SAVE"
1858
		setsave XVID_OPTS $HIGH_XVID_OPTS "$SAVE"
1859
		setsave MP3_ABITRATE $HIGH_MP3_ABITRATE "$SAVE"
1860
		setsave X264_CQ $HIGH_X264_CQ "$SAVE"
1861
		setsave X264EXT_OPTS "level_idc=31:$HIGH_X264EXT_OPTS" "$SAVE"
1862
		setsave X264_OPTS "level_idc=31:$HIGH_X264HIGH_OPTS" "$SAVE"
1863
		setsave AAC_AQUAL $HIGH_AAC_AQUAL "$SAVE"
1864
		setsave OGG_AQUAL $HIGH_OGG_AQUAL "$SAVE"
1865
	elif echo "$QLEVEL" | grep -i "med" >/dev/null 2>&1
1866
	then
1867
		setsave SCALE43 $MED_SCALE43 "$SAVE"
1868
		setsave SCALE169 $MED_SCALE169 "$SAVE"
1869
		setsave LAVC_CQ $MED_LAVC_CQ "$SAVE"
1870
		setsave LAVC_OPTS $MED_LAVC_OPTS "$SAVE"
1871
		setsave XVID_CQ $MED_XVID_CQ "$SAVE"
1872
		setsave XVID_OPTS $MED_XVID_OPTS "$SAVE"
1873
		setsave MP3_ABITRATE $MED_MP3_ABITRATE "$SAVE"
1874
		setsave X264_CQ $MED_X264_CQ "$SAVE"
1875
		setsave X264EXT_OPTS "level_idc=31:$MED_X264EXT_OPTS" "$SAVE"
1876
		setsave X264_OPTS "level_idc=31:$MED_X264HIGH_OPTS" "$SAVE"
1877
		setsave AAC_AQUAL $MED_AAC_AQUAL "$SAVE"
1878
		setsave OGG_AQUAL $MED_OGG_AQUAL "$SAVE"
1879
	elif echo "$QLEVEL" | grep -i "low" >/dev/null 2>&1
1880
	then
1881
		setsave SCALE43 $LOW_SCALE43 "$SAVE"
1882
		setsave SCALE169 $LOW_SCALE169 "$SAVE"
1883
		setsave LAVC_CQ $LOW_LAVC_CQ "$SAVE"
1884
		setsave LAVC_OPTS $LOW_LAVC_OPTS "$SAVE"
1885
		setsave XVID_CQ $LOW_XVID_CQ "$SAVE"
1886
		setsave XVID_OPTS $LOW_XVID_OPTS "$SAVE"
1887
		setsave MP3_ABITRATE $LOW_MP3_ABITRATE "$SAVE"
1888
		setsave X264_CQ $LOW_X264_CQ "$SAVE"
1889
		setsave X264EXT_OPTS "level_idc=30:$LOW_X264EXT_OPTS" "$SAVE"
1890
		setsave X264_OPTS "level_idc=30:$LOW_X264HIGH_OPTS" "$SAVE"
1891
		setsave AAC_AQUAL $LOW_AAC_AQUAL "$SAVE"
1892
		setsave OGG_AQUAL $LOW_OGG_AQUAL "$SAVE"
1893
	elif echo "$QLEVEL" | egrep -i "480" >/dev/null 2>&1
1894
	then
1895
		# 480 scale, high everything else
1896
		setsave SCALE43 $FE_SCALE43 "$SAVE"
1897
		setsave SCALE169 $FE_SCALE169 "$SAVE"
1898
		setsave LAVC_CQ $HIGH_LAVC_CQ "$SAVE"
1899
		setsave LAVC_OPTS $HIGH_LAVC_OPTS "$SAVE"
1900
		setsave XVID_CQ $HIGH_XVID_CQ "$SAVE"
1901
		setsave XVID_OPTS $HIGH_XVID_OPTS "$SAVE"
1902
		setsave MP3_ABITRATE $HIGH_MP3_ABITRATE "$SAVE"
1903
		setsave X264_CQ $HIGH_X264_CQ "$SAVE"
1904
		setsave X264EXT_OPTS "level_idc=31:$HIGH_X264EXT_OPTS" "$SAVE"
1905
		setsave X264_OPTS "level_idc=31:$HIGH_X264HIGH_OPTS" "$SAVE"
1906
		setsave AAC_AQUAL $HIGH_AAC_AQUAL "$SAVE"
1907
		setsave OGG_AQUAL $HIGH_OGG_AQUAL "$SAVE"
1908
	elif echo "$QLEVEL" | egrep -i "576" >/dev/null 2>&1
1909
	then
1910
		# 576 scale, high everything else
1911
		setsave SCALE43 $FS_SCALE43 "$SAVE"
1912
		setsave SCALE169 $FS_SCALE169 "$SAVE"
1913
		setsave LAVC_CQ $HIGH_LAVC_CQ "$SAVE"
1914
		setsave LAVC_OPTS $HIGH_LAVC_OPTS "$SAVE"
1915
		setsave XVID_CQ $HIGH_XVID_CQ "$SAVE"
1916
		setsave XVID_OPTS $HIGH_XVID_OPTS "$SAVE"
1917
		setsave MP3_ABITRATE $HIGH_MP3_ABITRATE "$SAVE"
1918
		setsave X264_CQ $HIGH_X264_CQ "$SAVE"
1919
		setsave X264EXT_OPTS "level_idc=31:$HIGH_X264EXT_OPTS" "$SAVE"
1920
		setsave X264_OPTS "level_idc=31:$HIGH_X264HIGH_OPTS" "$SAVE"
1921
		setsave AAC_AQUAL $HIGH_AAC_AQUAL "$SAVE"
1922
		setsave OGG_AQUAL $HIGH_OGG_AQUAL "$SAVE"
1923
	elif echo "$QLEVEL" | egrep -i "720" >/dev/null 2>&1
1924
	then
1925
		# 720 scale, high everything else
1926
		setsave SCALE43 $ST_SCALE43 "$SAVE"
1927
		setsave SCALE169 $ST_SCALE169 "$SAVE"
1928
		setsave LAVC_CQ $HIGH_LAVC_CQ "$SAVE"
1929
		setsave LAVC_OPTS $HIGH_LAVC_OPTS "$SAVE"
1930
		setsave XVID_CQ $HIGH_XVID_CQ "$SAVE"
1931
		setsave XVID_OPTS $HIGH_XVID_OPTS "$SAVE"
1932
		setsave MP3_ABITRATE $HIGH_MP3_ABITRATE "$SAVE"
1933
		setsave X264_CQ $HIGH_X264_CQ "$SAVE"
1934
		setsave X264EXT_OPTS "level_idc=41:$HIGH_X264EXT_OPTS" "$SAVE"
1935
		setsave X264_OPTS "level_idc=41:$HIGH_X264HIGH_OPTS" "$SAVE"
1936
		setsave AAC_AQUAL $HIGH_AAC_AQUAL "$SAVE"
1937
		setsave OGG_AQUAL $HIGH_OGG_AQUAL "$SAVE"
1938
	elif echo "$QLEVEL" | grep -i "1080" >/dev/null 2>&1
1939
	then
1940
		# 1080 scale, high everything else
1941
		setsave SCALE43 $TE_SCALE43 "$SAVE"
1942
		setsave SCALE169 $TE_SCALE169 "$SAVE"
1943
		setsave LAVC_CQ $HIGH_LAVC_CQ "$SAVE"
1944
		setsave LAVC_OPTS $HIGH_LAVC_OPTS "$SAVE"
1945
		setsave XVID_CQ $HIGH_XVID_CQ "$SAVE"
1946
		setsave XVID_OPTS $HIGH_XVID_OPTS "$SAVE"
1947
		setsave MP3_ABITRATE $HIGH_MP3_ABITRATE "$SAVE"
1948
		setsave X264_CQ $HIGH_X264_CQ "$SAVE"
1949
		setsave X264EXT_OPTS "level_idc=42:$HIGH_X264EXT_OPTS" "$SAVE"
1950
		setsave X264_OPTS "level_idc=42:$HIGH_X264HIGH_OPTS" "$SAVE"
1951
		setsave AAC_AQUAL $HIGH_AAC_AQUAL "$SAVE"
1952
		setsave OGG_AQUAL $HIGH_OGG_AQUAL "$SAVE"
1953
	fi
1954
	scriptlog INFO "Changed to $QLEVEL quality."
1955
}
1956
1957
setaudiotracks() {
1958
	local TMP=$1
1959
	local SAVE=$2
1960
	if [[ $TMP =~ ^([0-9]+(:[a-z]{3})?(,|$))+$ ]]
1961
	then
1962
		if echo $TMP | egrep -q "[1-9]" && ! is24ormore
1963
		then
1964
			scriptlog ERROR "Audio track selection is only supported on MythTV >= 0.24"
1965
			TMP=$(echo $TMP | sed "s/[1-9]/0/g")
1966
		fi
1967
		if [ $CONTYPE != "mkv" -a $CONTYPE != "mp4" ]
1968
		then
1969
			if echo $TMP | grep -q ","
1970
			then
1971
				scriptlog ERROR "Multiple audio tracks are only supported in mkv and mp4"
1972
				setsave ATRACKS "${TMP/,*/}" "$SAVE"
1973
			fi
1974
		else
1975
			setsave ATRACKS "$TMP" "$SAVE"
1976
		fi
1977
	else
1978
		scriptlog ERROR "Cannot parse audio tracks info"
1979
		setsave ATRACKS 0 "$SAVE"
1980
	fi
1981
	scriptlog DEBUG "Audio track definitions: $ATRACKS"
1982
}
1983
1984
parsetitle() {
1985
	local DATA=$@
1986
	while [[ ${DATA} =~ ([a-z]+)\|([^|]*)($| ) ]]; do
1987
		M=${BASH_REMATCH[0]}
1988
		[ -n "${DATA%%$M*}" ] && setsave SUBTITLE "${DATA%% $M*}" "true"
1989
		DATA=${DATA#*$M}
1990
		T=${BASH_REMATCH[1]}
1991
		D=${BASH_REMATCH[2]}
1992
		case $T in
1993
			[tT]) setsave TITLE "$D" "true" ;;
1994
			[sS]) setsave SUBTITLE "$D" "true" ;;
1995
			[nN]) setsave META_SEASON "$D" "true" ;;
1996
			[eE]) setsave META_EPISODE "$D" "true" ;;
1997
			[aA]) setsave META_ARTIST "$D" "true" ;;
1998
			[rR]) setsave META_DIRECTOR "$D" "true" ;;
1999
			[bB]) setsave META_ALBUM "$D" "true" ;;
2000
			[cC]) setsave META_COMMENT "$D" "true" ;;
2001
			[lL]) setsave META_LOCATION "$D" "true" ;;
2002
			[yYdD]) if [[ $D =~ ^[0-9]{4}$ ]]; then
2003
				date=$D
2004
			      elif [[ $D =~ ^([0-9]{4})[^0-9]([0-9]{2})[^0-9]([0-9]{2})$ ]]; then
2005
				date=${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}
2006
			      elif [[ $D =~ ^([0-9]{2})[^0-9]([0-9]{2})[^0-9]([0-9]{4})$ ]]; then
2007
				date=${BASH_REMATCH[3]}.${BASH_REMATCH[2]}.${BASH_REMATCH[1]}
2008
			      else
2009
				scriptlog ERROR "Wrong date: $D"
2010
				continue
2011
			      fi
2012
			      setsave META_DATE "$date" "true"
2013
			      ;;
2014
			[qQ]) setquality "$D" "true" ;;
2015
			[fF]) setcontype "$D" "true" ;;
2016
			"aud") setaudiotracks "$D" "true" ;;
2017
			"asp") setaspect "$D" "true" ;;
2018
			"den") setdenoise "$D" "true" ;;
2019
			"deb") setdeblock "$D" "true" ;;
2020
			"dei") setdeinterlace "$D" "true" ;;
2021
			"inv") setinvtelecine "$D" "true" ;;	
2022
			"crop") setcrop "$D" "true" ;;
2023
			"del") setdeleterec "$D" "true" ;;
2024
			"chap") setchapterduration "$D" "true" ;;
2025
			"chapf") setchapterfile "$D" "true" ;;
2026
			"dir") [ "${D:0:1}" == "/" ] && setcopydir "$D" "true" || setcopydir "$COPYDIR/$D" "true" ;;
2027
			"pass") setpass "$D" "true" ;;
2028
			*) scriptlog ERROR "Unknown tag: $T|$D" ;;
2029
		esac
2030
	done
2031
}
2032
2033
stoptime() {
2034
local STARTSECS=$1
2035
local MAXRUNHOURS=$2
2036
local CURSECS
2037
local ENDSECS
2038
	[ "$MAXRUNHOURS" = "NA" ] && return 1
2039
	CURSECS=$(date +%s)
2040
	ENDSECS=$(( $STARTSECS + ( $MAXRUNHOURS * 60 * 60 ) ))
2041
	[ "$ENDSECS" -gt "$CURSECS" ] && return 1 || return 0
2042
}
2043
2044
checkoutput() {
2045
local INPUT="$1"
2046
local OUTPUT="$2"
2047
local MENCODERRES="$3"
2048
local OUTPUTCHECKS="$4"
2049
local VIDFOR
2050
local OUTSIZE
2051
local INSIZE
2052
local RAT
2053
local SCANOUTFILE
2054
local LCOUNT
2055
local ECOUNT
2056
local INFRAMES
2057
local OUTFRAMES
2058
local DIFF
2059
	if echo "$OUTPUTCHECKS" | grep -v "NOSIZE" >/dev/null 2>&1
2060
	then
2061
		scriptlog INFO "Checking output size."
2062
		OUTSIZE=$(stat -c %s "$OUTPUT" 2>/dev/null || echo 0)
2063
		if [ "$OUTSIZE" -eq 0 ]
2064
		then
2065
			scriptlog ERROR "$OUTPUT zero length."
2066
			scriptlog INFO "This check can be disabled with --outputchecks=NOSIZE"
2067
			return 1
2068
		fi
2069
	fi
2070
2071
	if echo "$OUTPUTCHECKS" | grep -v "NOVIDINFO" >/dev/null 2>&1
2072
	then
2073
		scriptlog INFO "Checking output video info."
2074
		VIDFOR=$(getvidinfo "$OUTPUT" video_format)
2075
		case $VIDFOR in
2076
			MPEG4|AVC|XVID|DIVX|H264)
2077
				true
2078
			;;
2079
			*)
2080
				scriptlog ERROR "$OUTPUT ($VIDFOR) does not look like correct avi/mp4/mkv file."
2081
				scriptlog INFO "This check can be disabled with --outputchecks=NOVIDINFO"
2082
				return 1
2083
			;;
2084
		esac
2085
	fi
2086
2087
	if ! hascutlist $CHANID $STARTTIME && echo "$OUTPUTCHECKS" | grep -v "NOSIZERATIO" >/dev/null 2>&1
2088
	then
2089
		scriptlog INFO "Checking input/output size ratio."
2090
		INSIZE=$(stat -c %s "$INPUT" 2>/dev/null || echo 0)
2091
		RAT=$(( $INSIZE / $OUTSIZE ))
2092
		if [ "$RAT" -gt 16 ]
2093
		then
2094
			scriptlog ERROR "ratio of $RAT between $INPUT and $OUTPUT sizes greater than 16."
2095
			scriptlog INFO "This check can be disabled with --outputchecks=NOSIZERATIO"
2096
			return 1
2097
		fi
2098
	fi
2099
2100
	if echo "$OUTPUTCHECKS" | grep -v "NOFRAMECOUNT" >/dev/null 2>&1 && [ -f "$MENCODERRES" ]
2101
	then
2102
		scriptlog INFO "Checking input/output frame count."
2103
		INFRAMES=$(tail -40 "$MENCODERRES" | awk '/Video stream:/ {F=$12} END {print F}')
2104
		OUTFRAMES=$(nice mencoder -nosound -ovc frameno -vc null -o /dev/null "$OUTPUT" | awk '/Video stream:/ {F=$12} END {print F}')
2105
		scriptlog INFO "Input frames $INFRAMES $INPUT."
2106
		scriptlog INFO "Output frames $OUTFRAMES $OUTPUT."
2107
		if echo ${INFRAMES} : ${OUTFRAMES} | grep '[0-9] : [0-9]' >/dev/null 2>&1
2108
		then
2109
			DIFF=$([ $INFRAMES -gt $OUTFRAMES ] && echo $(( $INFRAMES - $OUTFRAMES )) || echo $(( $OUTFRAMES - $INFRAMES )))
2110
		else
2111
			scriptlog ERROR "Could not get frame count."
2112
			scriptlog INFO "This check can be disabled with --outputchecks=NOFRAMECOUNT"
2113
			return 1
2114
		fi
2115
		if [ "$DIFF" -gt 10 ]
2116
		then
2117
			scriptlog ERROR "Frame count difference of $DIFF between $INPUT and $OUTPUT greater than 10."
2118
			scriptlog INFO "This check can be disabled with --outputchecks=NOFRAMECOUNT"
2119
			return 1
2120
		fi
2121
	fi
2122
2123
	if echo "$OUTPUTCHECKS" | grep -v "NOSCAN" >/dev/null 2>&1
2124
	then
2125
		scriptlog INFO "Scanning output for errors. (Takes a long time)"
2126
		SCANOUTFILE="${FIFODIR}/mplayerscan-out"
2127
		nice mplayer -nojoystick -nolirc -nomouseinput -vo null -ao null -speed 10 "$OUTPUT" 2>&1 | tr '\r' '\n' >$SCANOUTFILE 2>&1
2128
		LCOUNT=$(wc -l $SCANOUTFILE 2>/dev/null | awk '{T=$1} END {if(T>0){print T}else{print 0}}')
2129
		if [ "$LCOUNT" -lt 1000 ]
2130
		then
2131
			scriptlog ERROR "mplayer line count of $LCOUNT to low on $OUTPUT."
2132
			scriptlog INFO "This check can be disabled with --outputchecks=NOSCAN"
2133
			return 1
2134
		fi
2135
		ECOUNT=$(egrep -ic 'sync|error|skip|damaged|overflow' $SCANOUTFILE)
2136
		if [ "$ECOUNT" -gt "$MPLAYER_ERROR_COUNT" ]
2137
		then
2138
			scriptlog ERROR "mplayer error count too great ($ECOUNT > $MPLAYER_ERROR_COUNT) on $OUTPUT."
2139
			scriptlog INFO "You can change the error limit variable MPLAYER_ERROR_COUNT at top of script or"
2140
			scriptlog INFO "The check can be disabled with --outputchecks=NOSCAN"
2141
			return 1
2142
		fi
2143
	fi
2144
2145
	return 0
2146
}
2147
2148
getcategory() {
2149
local CHANID="$1"
2150
local STARTTIME="$2"
2151
local DATA
2152
	[ -n "$CHANID" ] || return 1
2153
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
2154
	select category from recorded where chanid = $CHANID and starttime = "$STARTTIME";
2155
	EOF
2156
	)
2157
	echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]'
2158
}
2159
2160
getplot() {
2161
local CHANID="$1"
2162
local STARTTIME="$2"
2163
local DATA
2164
	[ -n "$CHANID" ] || return 1
2165
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
2166
	select description from recorded where chanid = $CHANID and starttime = "$STARTTIME";
2167
	EOF
2168
	)
2169
	echo $DATA | tr -d '[:cntrl:]' | tr -d '[:punct:]'
2170
}
2171
2172
getyear() {
2173
local CHANID="$1"
2174
local STARTTIME="$2"
2175
local DATA
2176
	[ -n "$CHANID" ] || return 1
2177
	# STARTTIME is not always the same in both tables for matching programs. ???
2178
	DATA=$(mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
2179
	select airdate from recorded a,recordedprogram b
2180
	where a.chanid = $CHANID and a.starttime = "$STARTTIME" and a.chanid = b.chanid
2181
	and a.title = b.title and a.subtitle = b.subtitle;
2182
	EOF
2183
	)
2184
	[ -n "$DATA" -a $DATA -gt 1800 ] && echo $DATA || echo $(date +%Y)
2185
}
2186
2187
2188
genchapfile() {
2189
local FILE="$1"
2190
local DURATION=$(( $2 * 60 ))
2191
local CONTYPE="$3"
2192
local CHAPTERFILE="${FIFODIR}/chapters.txt"
2193
local LENGTH
2194
local CHAPTER
2195
local COUNT
2196
local CHAPMINS
2197
local CHAPHOURS
2198
local CHAPSECS
2199
	{
2200
	if [ "$CONTYPE" != "mkv" -a "$CONTYPE" != "mp4" ]
2201
	then
2202
		scriptlog ERROR "Container type does not support chapters."
2203
		return 1
2204
	fi
2205
	LENGTH=$(getlength "$FILE") # Must use midentify
2206
	LENGTH=$(echo $LENGTH | cut -d'.' -f1)
2207
	if [ -z "$LENGTH"  -o "$LENGTH" -lt 1 ]
2208
	then
2209
		scriptlog ERROR "Invalid Length $LENGTH seconds"
2210
		return 1
2211
	else
2212
		scriptlog INFO "Length $LENGTH seconds, chapter every $DURATION seconds. $(( ( $LENGTH / $DURATION ) + 1 )) Chapters"
2213
	fi
2214
	CHAPTER=0 ; COUNT=1
2215
	touch "$CHAPTERFILE"
2216
	while [ "$CHAPTER" -lt "$LENGTH" ]
2217
	do
2218
		scriptlog DEBUG "CHAPTERFILE $CHAPTERFILE CHAPTER $CHAPTER LENGTH $LENGTH"
2219
		CHAPMINS=$(( $CHAPTER / 60 ))
2220
		CHAPHOURS=$(( $CHAPMINS / 60 ))
2221
		CHAPMINS=$(( $CHAPMINS - ( $CHAPHOURS * 60 ) ))
2222
		CHAPSECS=$(( $CHAPTER - ( ( $CHAPHOURS * 60 * 60 ) + ( $CHAPMINS * 60 ) ) ))
2223
		printf 'CHAPTER%s=%02d:%02d:%02d.000\n' ${COUNT} ${CHAPHOURS} ${CHAPMINS} ${CHAPSECS} >> "$CHAPTERFILE"
2224
		echo "CHAPTER${COUNT}NAME=Chapter $COUNT" >> "$CHAPTERFILE"
2225
		COUNT=$(( $COUNT + 1 ))
2226
		CHAPTER=$(( $CHAPTER + $DURATION ))
2227
	done
2228
	} >/dev/null 2>&1
2229
	echo "$CHAPTERFILE"
2230
}
2231
2232
encloseincontainer() {
2233
local OUTBASE="$1"
2234
local FPS="$2"
2235
local AUDEXT="$3"
2236
local CONTYPE="$4"
2237
local ASPECT="$5"
2238
local ATRACKS="$6"
2239
local TITLE="$7"
2240
local CHAPTERFILE="$8"
2241
local CHAPTERS=""
2242
local RET
2243
local MKVTRACKS
2244
local MP4TRACKS
2245
local MKVTITLE
2246
local TRACK
2247
local FILE
2248
	for ATRACK in ${ATRACKS//,/ }
2249
	do
2250
		TRACK=${ATRACK:0:1}
2251
		LANG=${ATRACK:2:3}
2252
		FILE=${OUTBASE}_audio${TRACK}.${AUDEXT}
2253
2254
		if [ ! -f "$FILE" ]
2255
		then
2256
			scriptlog ERROR "$FILE does not exist."
2257
			return 1
2258
		fi
2259
2260
		[ -n "$LANG" ] && MKVTRACKS="$MKVTRACKS --language 0:$LANG"
2261
		MKVTRACKS="$MKVTRACKS $FILE"
2262
2263
		MP4TRACKS="$MP4TRACKS -add $FILE"
2264
		[ -n "$LANG" ] && MP4TRACKS="${MP4TRACKS}:lang=$LANG"
2265
	done
2266
	if [ -f "${OUTBASE}_video.h264" ]
2267
	then
2268
		if [ "$CONTYPE" = "mkv" ]
2269
		then
2270
			[ -f "$CHAPTERFILE" ] && CHAPTERS="--chapters $CHAPTERFILE"
2271
	                MKVTITLE="$TITLE"
2272
                	[ -n "$SUBTITLE" ] && COPYFILE="$MKVTITLE - $SUBTITLE"
2273
        	        [ -n "$META_ARTIST" ] && MKVTITLE="$META_ARTIST - $MKVTITLE"
2274
2275
			cat > ${OUTBASE}_tags.xml <<-EOF
2276
			<?xml version="1.0" encoding="UTF-8"?>
2277
			<!DOCTYPE Tags SYSTEM "matroskatags.dtd">
2278
			<Tags>
2279
			  <Tag>
2280
			    <Targets>
2281
			EOF
2282
2283
			# music video
2284
			if [ -n "$META_ALBUM" ]
2285
			then
2286
				cat >> ${OUTBASE}_tags.xml <<-EOF
2287
				      <TargetTypeValue>50</TargetTypeValue>
2288
				    </Targets>
2289
				    <Simple>
2290
				      <Name>TITLE</Name>
2291
				      <String>$META_ALBUM</String>
2292
				    </Simple>
2293
				  </Tag>
2294
				  <Tag>
2295
				    <Targets>
2296
				      <TargetTypeValue>30</TargetTypeValue>
2297
				    </Targets>
2298
				    <Simple>
2299
				      <Name>TITLE</Name>
2300
				      <String>$TITLE</String>
2301
				    </Simple>
2302
				EOF
2303
2304
			# series episode
2305
			elif [ -n "$META_EPISODE" ]
2306
			then
2307
				cat >> ${OUTBASE}_tags.xml <<-EOF
2308
				      <TargetTypeValue>70</TargetTypeValue>
2309
				    </Targets>
2310
				    <Simple>
2311
				      <Name>TITLE</Name>
2312
				      <String>$TITLE</String>
2313
				    </Simple>
2314
				  </Tag>
2315
				EOF
2316
				if [ -n "$META_SEASON" ]
2317
				then
2318
					cat >> ${OUTBASE}_tags.xml <<-EOF
2319
					  <Tag>
2320
					    <Targets>
2321
					      <TargetTypeValue>50</TargetTypeValue>
2322
					    </Targets>
2323
					    <Simple>
2324
					      <Name>PART_NUMBER</Name>
2325
					      <String>$META_SEASON</String>
2326
					    </Simple>
2327
					  </Tag>
2328
					EOF
2329
				fi
2330
				cat >> ${OUTBASE}_tags.xml <<-EOF
2331
				  <Tag>
2332
				    <Targets>
2333
				      <TargetTypeValue>30</TargetTypeValue>
2334
				    </Targets>
2335
				    <Simple>
2336
				      <Name>PART_NUMBER</Name>
2337
				      <String>$META_EPISODE</String>
2338
				    </Simple>
2339
				    <Simple>
2340
				      <Name>TITLE</Name>
2341
				      <String>$SUBTITLE</String>
2342
				    </Simple>
2343
				EOF
2344
2345
			# general
2346
			else
2347
				cat >> ${OUTBASE}_tags.xml <<-EOF
2348
				      <TargetTypeValue>50</TargetTypeValue>
2349
				    </Targets>
2350
				    <Simple>
2351
				      <Name>TITLE</Name>
2352
				      <String>$TITLE</String>
2353
				    </Simple>
2354
				EOF
2355
				
2356
		        	[ -n "$SUBTITLE" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2357
				    <Simple>
2358
				      <Name>SUBTITLE</Name>
2359
				      <String>$SUBTITLE</String>
2360
				    </Simple>
2361
				EOF
2362
			fi
2363
2364
			[ -n "$META_ARTIST" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2365
			    <Simple>
2366
			      <Name>ARTIST</Name>
2367
			      <String>$META_ARTIST</String>
2368
			    </Simple>
2369
			EOF
2370
2371
			[ -n "$META_DIRECTOR" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2372
			    <Simple>
2373
			      <Name>DIRECTOR</Name>
2374
			      <String>$META_DIRECTOR</String>
2375
			    </Simple>
2376
			EOF
2377
2378
			[ -n "$META_DATE" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2379
			    <Simple>
2380
			      <Name>DATE_RELEASED</Name>
2381
			      <String>$META_DATE</String>
2382
			    </Simple>
2383
			EOF
2384
2385
			[ -n "$META_COMMENT" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2386
			    <Simple>
2387
			      <Name>COMMENT</Name>
2388
			      <String>$META_COMMENT</String>
2389
			    </Simple>
2390
			EOF
2391
2392
			[ -n "$META_LOCATION" ] && cat >> ${OUTBASE}_tags.xml <<-EOF
2393
			    <Simple>
2394
			      <Name>RECORDING_LOCATION</Name>
2395
			      <String>$META_LOCATION</String>
2396
			    </Simple>
2397
			EOF
2398
2399
			cat >> ${OUTBASE}_tags.xml <<-EOF
2400
			  </Tag>
2401
			</Tags>
2402
			EOF
2403
2404
			if [ "$MKVMERGE251BUG" = "YES" ]
2405
			then
2406
				scriptlog DEBUG Muxing: LANG=C mkvmerge --global-tags "${OUTBASE}_tags.xml" --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$MKVTITLE" $CHAPTERS \
2407
				"${OUTBASE}_video.h264" $MKVTRACKS -o "${OUTBASE}.mkv"
2408
				LANG=C mkvmerge --global-tags "${OUTBASE}_tags.xml" --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$MKVTITLE" $CHAPTERS \
2409
				"${OUTBASE}_video.h264" $MKVTRACKS -o "${OUTBASE}.mkv"
2410
				RET=$? ; [ $RET -eq 1 ] && RET=0 # mkvmerge return code of 1 is only a warning
2411
			else
2412
				scriptlog DEBUG Muxing: mkvmerge --global-tags "${OUTBASE}_tags.xml" --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$MKVTITLE" $CHAPTERS \
2413
				"${OUTBASE}_video.h264" $MKVTRACKS -o "${OUTBASE}.mkv"
2414
				mkvmerge --global-tags "${OUTBASE}_tags.xml" --default-duration 0:${FPS}fps --aspect-ratio 0:${ASPECT} --title "$MKVTITLE" $CHAPTERS \
2415
				"${OUTBASE}_video.h264" $MKVTRACKS -o "${OUTBASE}.mkv"
2416
				RET=$? ; [ $RET -eq 1 ] && RET=0 # mkvmerge return code of 1 is only a warning
2417
			fi
2418
		elif [ "$CONTYPE" = "mp4" ]
2419
		then
2420
			[ -f "$CHAPTERFILE" ] && CHAPTERS="-chap $CHAPTERFILE"
2421
			MP4Box -add "${OUTBASE}_video.h264:par=1:1" $MP4TRACKS -fps $FPS $CHAPTERS "${OUTBASE}.mp4"
2422
			RET=$?
2423
		fi
2424
		if [ $RET -eq 0 ]
2425
		then
2426
			[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}_video.h264" "${OUTBASE}_audio*.${AUDEXT}" "${OUTBASE}_tags.xml"
2427
		else
2428
			[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}_video.h264" "${OUTBASE}_audio*.${AUDEXT}" "${OUTBASE}_tags.xml" "${OUTBASE}.mkv" >/dev/null 2>&1
2429
			return 1
2430
		fi
2431
	else
2432
		scriptlog ERROR "${OUTBASE}_video.h264 does not exist."
2433
		return 1
2434
	fi
2435
	return 0
2436
}
2437
2438
logtranstime () {
2439
local START=$1
2440
local END=$2
2441
local ORIGINALFILESIZE=$3
2442
local NEWFILESIZE=$4
2443
	TMP=$(( $(date -u -d"${END}" +%s) - $(date -u -d"${START}" +%s) ))
2444
	DAYS=$(( $TMP / 60 / 60 / 24 ))
2445
	HOURS=$(( $TMP / 60 / 60 - ($DAYS * 24) ))
2446
	MINUTES=$(( $TMP / 60 - ( ($HOURS * 60)+($DAYS * 24 * 60) ) ))
2447
	SECONDS=$(( $TMP - ( ($MINUTES * 60)+($HOURS * 60 * 60)+($DAYS * 24 * 60 * 60) ) ))
2448
	scriptlog INFO "RUNTIME: $DAYS days $HOURS hours $MINUTES minutes and $SECONDS seconds. Original filesize: $ORIGINALFILESIZE New filesize: $NEWFILESIZE"
2449
}
2450
2451
boinccontrol() {
2452
local BOINCCOMMAND="$1"
2453
# BOINCPASSWD global
2454
	[ -n "$BOINCPASSWD" ] || return 1
2455
	for p in $(boinccmd --host "localhost" --passwd "$BOINCPASSWD" --get_project_status | awk '/master URL:/ {print $3}')
2456
	do
2457
		if boinccmd --host "localhost" --passwd "$BOINCPASSWD" --project "$p" "$BOINCCOMMAND" >/dev/null 2>&1
2458
		then
2459
			scriptlog INFO "Boinc project $p $BOINCCOMMAND."
2460
		else
2461
			scriptlog INFO "Boinc project $p FAILED to $BOINCCOMMAND."
2462
		fi
2463
	done
2464
}
2465
2466
cleanup() {
2467
local SIG="$1"
2468
local JOBID="$2"
2469
local OUTPUT="$3"
2470
local OUTBASE
2471
local TRANPID
2472
	scriptlog DEBUG "$SIG Clean up."
2473
	if [ "$SIG" = "ABRT" ]
2474
	then
2475
		scriptlog ERROR "Job Aborted. Removing incomplete $OUTPUT."
2476
		OUTBASE=$(echo "$OUTPUT" | sed -e 's/\.[ma][pv][4i]$//')
2477
		[ "$DEBUG" != "ON" ] && rm -f "${OUTBASE}.avi" "${OUTBASE}_video.h264" "${OUTBASE}_audio*.aac" "${OUTBASE}_audio*.ogg" "${OUTBASE}_tags.xml" "${OUTBASE}.mp4" "${OUTBASE}.mkv" >/dev/null 2>&1
2478
	fi
2479
2480
	TRANPID=$(jobs -l | awk '/mythtranscode/ {P=$2" "P} END {print P}')
2481
	if [ -n "$TRANPID" ]
2482
	then
2483
		scriptlog DEBUG "Killing mythtranscode [$TRANPID]"
2484
		ps -p $TRANPID >/dev/null 2>&1 && kill $TRANPID >/dev/null 2>&1
2485
	fi
2486
2487
	# resume boinc
2488
	boinccontrol "resume"
2489
2490
	if [ "$FINALEXIT" -eq 0 ]
2491
	then
2492
		[ "$DEBUG" != "ON" ] && rm -rf "$FIFODIR" >/dev/null 2>&1
2493
		scriptlog INFO "Exiting. Successful."
2494
		if [ "$JOBID" -ne 99999999 ]
2495
		then
2496
			setjobqueuestatus "$JOBID" "FINISHED"
2497
			setjobqueuecomment "$JOBID" "[${$}] Successfully Completed"
2498
		fi
2499
		exit 0
2500
	else
2501
		scriptlog INFO "Exiting. Errored."
2502
		if [ "$JOBID" -ne 99999999 ]
2503
		then
2504
			setjobqueuestatus "$JOBID" "ERRORED"
2505
			setjobqueuecomment "$JOBID" "[${$}] Errored"
2506
		fi
2507
		# Only error code jobqueue.cpp interprets is 246. This is translated to "unable to find executable".
2508
		#scriptlog ERROR "This error could be for many reasons. Mythtv will report unable to find executable, this is incorrect."
2509
		is21orless && exit 246 || exit 1
2510
	fi
2511
}
2512
2513
2514
MYSQLLIST="$MYSQLTXT /home/mythtv/.mythtv/mysql.txt ${HOME}/.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"
2515
for m in $MYSQLLIST
2516
do
2517
	[ -f $m ] && . $m && break
2518
done
2519
if [ -z "$DBName" ]
2520
then
2521
	echo "Can't find mysql.txt. Change MYSQLTXT variable at top of script with your mysql.txt path"
2522
	exit 1
2523
fi
2524
2525
##### BG Monitor #####################################
2526
# This will be fired off in background to update the jobqueue comment and process stop/pause/resume requests.
2527
if echo "$1" | egrep -i '\-\-monitor=' >/dev/null 2>&1
2528
then
2529
	readonly MONJOBID=$(echo "$1" | cut -d'=' -f2)
2530
	readonly MONPID="$2"
2531
	readonly MONTRANSOP="$3"
2532
	readonly LOGFILE="$4"
2533
	readonly DBLOGGING=$(getsetting "LogEnabled")
2534
2535
	[ "$MONJOBID" -ne 99999999 -a -n "$MONPID" ] || exit 1
2536
2537
	PAUSEALREADYPRINTED="" ; RESUMEALREADYPRINTED=""
2538
	
2539
	scriptlog INFO "Starting monitoring process."
2540
	sleep 5
2541
	while ps -p $MONPID >/dev/null 2>&1
2542
	do
2543
		JQCMD=$(getjobqueuecmds "$MONJOBID")
2544
		if [ "$JQCMD" = "PAUSE" ]
2545
		then
2546
			JQSTATUS=$(getjobqueuestatus "$MONJOBID")
2547
			if [ "$JQSTATUS" != "PAUSED" ]
2548
			then
2549
				MENCODERPID=$(ps --ppid $MONPID | awk '/mencoder/ {print $1}')
2550
				if [ -n "$MENCODERPID" ]
2551
				then
2552
					PAUSEALREADYPRINTED=""
2553
					STARTPAUSESECS=$(date +%s)
2554
					kill -s STOP $MENCODERPID
2555
					setjobqueuestatus "$MONJOBID" "PAUSED"
2556
					SAVEDCC=$(getjobqueuecomment "$MONJOBID")
2557
					setjobqueuecomment "$MONJOBID" "[$MONPID] Paused for 0 Seconds"
2558
					scriptlog STOP "Job Paused due to job queue pause request."
2559
				else
2560
					[ -z "$PAUSEALREADYPRINTED" ] && scriptlog ERROR "Sorry, could not pause. Will keep trying"
2561
					PAUSEALREADYPRINTED=TRUE
2562
				fi
2563
			else
2564
				NOW=$(date +%s)
2565
				PAUSESECS=$(( $NOW - $STARTPAUSESECS ))
2566
				PAUSEMINS=$(( $PAUSESECS / 60 ))
2567
				PAUSEHOURS=$(( $PAUSEMINS / 60 ))
2568
				PAUSEMINS=$(( $PAUSEMINS - ( $PAUSEHOURS * 60 ) ))
2569
				PAUSESECS=$(( $PAUSESECS - ( ( $PAUSEHOURS * 60 * 60 ) + ( $PAUSEMINS * 60 ) ) ))
2570
				setjobqueuecomment "$MONJOBID" "[$MONPID] Paused for $PAUSEHOURS Hrs $PAUSEMINS Mins $PAUSESECS Secs"
2571
			fi
2572
		elif [ "$JQCMD" = "RESUME" ]
2573
		then
2574
			JQSTATUS=$(getjobqueuestatus "$MONJOBID")
2575
			if [ "$JQSTATUS" != "RUNNING" ]
2576
			then
2577
				MENCODERPID=$(ps --ppid $MONPID | awk '/mencoder/ {print $1}')
2578
				if [ -n "$MENCODERPID" ]
2579
				then
2580
					RESUMEALREADYPRINTED=""
2581
					kill -s CONT $MENCODERPID
2582
					setjobqueuestatus "$MONJOBID" "RUNNING"
2583
					setjobqueuecomment "$MONJOBID" "$SAVEDCC"
2584
					scriptlog START "Job resumed due to job queue resume request."
2585
					setjobqueuecmds "$MONJOBID" "RUN"
2586
				else
2587
					[ -z "$RESUMEALREADYPRINTED" ] && scriptlog ERROR "Sorry, could not resume. Will keep trying"
2588
					RESUMEALREADYPRINTED=TRUE
2589
				fi
2590
			fi
2591
		elif [ "$JQCMD" = "STOP" ]
2592
		then
2593
			setjobqueuestatus "$MONJOBID" "ABORTING"
2594
			setjobqueuecomment "$MONJOBID" "[$MONPID] Stopping"
2595
			scriptlog STOP "Stopping due to job queue stop request."
2596
			setjobqueuecmds "$MONJOBID" "RUN"
2597
			kill -s ABRT $MONPID
2598
			sleep 2
2599
			kill $MONPID
2600
		elif [ "$JQCMD" = "RESTART" ]
2601
		then
2602
			scriptlog ERROR "Sorry, can't restart job."
2603
			setjobqueuecmds "$MONJOBID" "RUN"
2604
		else
2605
			CC=$(getjobqueuecomment "$MONJOBID")
2606
			if echo "$CC" | grep 'audio pass' >/dev/null 2>&1
2607
			then
2608
				PASSNU="audio pass"
2609
			elif echo "$CC" | grep 'Single video pass' >/dev/null 2>&1
2610
			then
2611
				PASSNU="Single video pass"
2612
			elif echo "$CC" | grep '1st video pass' >/dev/null 2>&1
2613
			then
2614
				PASSNU="1st video pass"
2615
			elif echo "$CC" | grep '2nd video pass' >/dev/null 2>&1
2616
			then
2617
				PASSNU="2nd video pass"
2618
			else
2619
				sleep 15
2620
				continue
2621
			fi
2622
			PCTLINE=$(tail -10 "$MONTRANSOP" | grep 'mythtranscode:' | cut -c39- | tail -1)
2623
			[ -n "$PASSNU" -a -n "$PCTLINE" ] && setjobqueuecomment "$MONJOBID" "[$MONPID] $PASSNU $PCTLINE"
2624
		fi
2625
		sleep 15
2626
	done
2627
	exit
2628
fi
2629
2630
##### Globals ########################################
2631
readonly CMD="$0"
2632
readonly LOGFILE="${LOGBASEDIR}/mythnuv2mkv${$}.log"
2633
readonly FIFODIR="${LOGBASEDIR}/mythnuv2mkv${$}"
2634
readonly MENCODEROP="${FIFODIR}/mencoder.op"
2635
readonly TRANSOP="${FIFODIR}/transcode.op"
2636
readonly STOPREQUEST="${FIFODIR}/STOPREQUEST"
2637
if ! tty >/dev/null 2>&1
2638
then
2639
	readonly BOLDON=""
2640
	readonly ALLOFF=""
2641
	readonly REDFG=""
2642
	readonly GREENFG=""
2643
	readonly COLOURORIG=""
2644
	[ "$DEBUG" = "ON" ] && exec 3>"${LOGBASEDIR}/DEBUG" || exec 3>/dev/null
2645
	exec 1>&3
2646
	exec 2>&3
2647
else
2648
	readonly BOLDON=`tput bold`
2649
	readonly ALLOFF=`tput sgr0`
2650
	readonly REDFG=`tput setaf 1`
2651
	readonly GREENFG=`tput setaf 2`
2652
	readonly COLOURORIG=`tput op`
2653
fi
2654
# DBLOGGING is reverse to shell true/false
2655
DBLOGGING=0
2656
OUTPUT=""
2657
JOBID=99999999
2658
FINALEXIT=0
2659
STARTSECS="NA"
2660
MAXRUNHOURS="NA"
2661
MKVMERGE251BUG="NO"
2662
2663
##### Main ###########################################
2664
if echo "$1" | egrep -i '\-help|\-usage|\-\?' >/dev/null 2>&1
2665
then
2666
	echo "$HELP"
2667
	exit 1
2668
fi
2669
2670
if [ "$CONTYPE" = "mkv" ]
2671
then
2672
	chkreqs "$MKVREQPROGS" "$MKVREQLIBS" || exit 1
2673
	versioncheck "mkvmerge"
2674
elif [ "$CONTYPE" = "mp4" ]
2675
then
2676
	chkreqs "$MP4REQPROGS" "$MP4REQLIBS" || exit 1
2677
elif [ "$CONTYPE" = "avi" ]
2678
then
2679
	chkreqs "$AVIREQPROGS" "$AVIREQLIBS" || exit 1
2680
fi
2681
if ! versioncheck "convert"
2682
then
2683
	scriptlog INFO "The program \"convert\" does not appear to be the ImageMagick one. This will only affect coverfile creation."
2684
fi
2685
2686
trap 'cleanup ABRT "$JOBID" "$OUTPUT"' INT ABRT
2687
trap 'touch $STOPREQUEST ; scriptlog INFO "USR1 received. Will stop after current file completes."' USR1
2688
trap 'cleanup EXIT "$JOBID"' EXIT
2689
mkdir -m 775 -p "${LOGBASEDIR}" >/dev/null 2>&1 || scriptlog ERROR "Could not create ${LOGBASEDIR}"
2690
mkdir -m 775 -p "${FIFODIR}" >/dev/null 2>&1 || scriptlog ERROR "Could not create ${FIFODIR}"
2691
[ -w "${LOGBASEDIR}" ] || scriptlog ERROR "${LOGBASEDIR} not writable"
2692
[ -w "${FIFODIR}" ] || scriptlog ERROR "${FIFODIR} not writable"
2693
[ ${FINALEXIT} ] || exit $FINALEXIT
2694
2695
# Set default quality
2696
[ -n "${QUALITY}" ] && setquality ${QUALITY}
2697
2698
for INPUT in "$@"
2699
do
2700
	if stoptime $STARTSECS $MAXRUNHOURS
2701
	then
2702
		scriptlog STOP "Stopping due to max runtime $MAXRUNHOURS."
2703
		scriptlog BREAK 
2704
		break
2705
	fi
2706
	if [ -f "$STOPREQUEST" ]
2707
	then
2708
		scriptlog STOP "Stopping due to USR1 request."
2709
		scriptlog BREAK 
2710
		break
2711
	fi
2712
2713
	# Jobid from myth user job %JOBID%
2714
	if echo "$INPUT" | grep -i '\-\-jobid=' >/dev/null 2>&1
2715
	then
2716
		JOBID=$(echo "$INPUT" | cut -d'=' -f2)
2717
		DBLOGGING=$(getsetting "LogEnabled")
2718
		continue
2719
	fi
2720
2721
	if echo "$INPUT" | grep -i '\-\-findtitle=' >/dev/null 2>&1
2722
	then
2723
		SEARCHTITLE=$(echo "$INPUT" | cut -d'=' -f2)
2724
		MATCHTITLE=$(findchanidstarttime "$SEARCHTITLE")	
2725
		echo "$MATCHTITLE"
2726
		exit 0
2727
	fi
2728
2729
	if echo "$INPUT" | grep -i '\-\-maxrunhours=' >/dev/null 2>&1
2730
	then
2731
		STARTSECS=$(date +%s)
2732
		MAXRUNHOURS=$(echo "$INPUT" | cut -d'=' -f2)
2733
		scriptlog INFO "Max Run Hours set to $MAXRUNHOURS."
2734
		continue
2735
	fi
2736
2737
	if echo "$INPUT" | grep -i '\-\-debugsg' >/dev/null 2>&1
2738
	then
2739
		DEBUGSG="ON"
2740
		scriptlog INFO "DEBUGSG set ON."
2741
		continue
2742
	fi
2743
	if echo "$INPUT" | grep -i '\-\-debug=' >/dev/null 2>&1
2744
	then
2745
		DEBUG=$(echo "$INPUT" | cut -d'=' -f2 | tr '[a-z]' '[A-Z]')
2746
		scriptlog INFO "Debug set to $DEBUG."
2747
		continue
2748
	fi
2749
	if echo "$INPUT" | grep -i '\-\-info=' >/dev/null 2>&1
2750
	then
2751
		INFO=$(echo "$INPUT" | cut -d'=' -f2 | tr '[a-z]' '[A-Z]')
2752
		scriptlog INFO "Info set to $INFO."
2753
		continue
2754
	fi
2755
	if echo "$INPUT" | grep -i '\-\-savenuv=' >/dev/null 2>&1
2756
	then
2757
		SAVENUV=$(echo "$INPUT" | cut -d'=' -f2 | tr '[a-z]' '[A-Z]')
2758
		scriptlog INFO "SaveNUV set to $SAVENUV."
2759
		continue
2760
	fi
2761
2762
	if echo "$INPUT" | grep -i '\-\-outputchecks=' >/dev/null 2>&1
2763
	then
2764
		OUTPUTCHECKS=$(echo "$INPUT" | cut -d'=' -f2 | tr '[a-z]' '[A-Z]')
2765
		scriptlog INFO "Output checks set to $OUTPUTCHECKS."
2766
		continue
2767
	fi
2768
2769
	shopt -s nocasematch
2770
	if [[ "$INPUT" =~ --(aspect|denoise|deblock|deinterlace|invtelecine|crop|deleterec|chapterduration|chapterfile|copydir|contype|pass|quality|audiotracks)\=(.*) ]]
2771
	then
2772
		set${BASH_REMATCH[1]} "${BASH_REMATCH[2]}"
2773
		continue
2774
	fi
2775
	shopt -u nocasematch
2776
2777
	if echo "$INPUT" | grep -i '\-\-chanid=' >/dev/null 2>&1
2778
	then
2779
		CHANID=$(echo "$INPUT" | cut -d'=' -f2)
2780
		continue
2781
	fi
2782
	if echo "$INPUT" | grep -i '\-\-starttime=' >/dev/null 2>&1
2783
	then
2784
		STARTTIME=$(echo "$INPUT" | cut -d'=' -f2)
2785
		if [ -z "$CHANID" ]
2786
		then
2787
			scriptlog ERROR "Skipping $STARTTIME. chanid not specified."
2788
			scriptlog ERROR "--chanid must be specified before --starttime."
2789
			scriptlog BREAK 
2790
			unset STARTTIME
2791
			continue
2792
		fi
2793
		if [ "$DEBUGSG" = "ON" ]
2794
		then
2795
			INPUT=$(getrecordfile "$CHANID" "$STARTTIME" "$DEBUGSG")
2796
			scriptlog INFO "$INPUT" 
2797
			scriptlog BREAK 
2798
			exit $FINALEXIT
2799
		fi
2800
		INPUT=$(getrecordfile "$CHANID" "$STARTTIME")
2801
		if [ -z "$INPUT" ]
2802
		then
2803
			scriptlog ERROR "Skipping $CHANID $STARTTIME. Did not match a recording."
2804
			scriptlog BREAK 
2805
			unset CHANID STARTTIME
2806
			continue
2807
		fi
2808
		if [ ! -f "$INPUT" ]
2809
		then
2810
			scriptlog ERROR "Could not find Recording. ($INPUT)"
2811
			scriptlog BREAK 
2812
			unset CHANID STARTTIME
2813
			continue
2814
		fi
2815
		TITLE=$(gettitle $CHANID $STARTTIME)
2816
		SUBTITLE=$(getsubtitle $CHANID $STARTTIME)
2817
		parsetitle $SUBTITLE
2818
		MTINFILE=""
2819
		MTSOURCE="--chanid $CHANID --starttime $STARTTIME"
2820
		hascutlist $CHANID $STARTTIME && MTSOURCE="--honorcutlist $MTSOURCE"
2821
		scriptlog INFO "$CHANID $STARTTIME matches $META_ARTIST - $TITLE - $SUBTITLE ($INPUT)"
2822
	else
2823
		echo "$INPUT" | grep '^\/' >/dev/null 2>&1 || INPUT="`pwd`/${INPUT}"
2824
		MTINFILE="--infile"
2825
		MTSOURCE="$INPUT"
2826
	fi
2827
2828
	if [ ! -f "$INPUT" ]
2829
	then
2830
		scriptlog ERROR "Skipping $INPUT does not exist."
2831
		scriptlog BREAK 
2832
		unset CHANID STARTTIME
2833
		continue
2834
	fi
2835
2836
	if echo "$INPUT" | grep -v '\.[nm][up][vg]$' >/dev/null 2>&1
2837
	then
2838
		scriptlog ERROR "Skipping $INPUT not a nuv or mpg file."
2839
		scriptlog BREAK 
2840
		unset CHANID STARTTIME
2841
		continue
2842
	fi
2843
2844
	OUTBASE=$(echo "$INPUT" | sed -e 's/\.[nm][up][vg]$//')
2845
	OUTPUT="${OUTBASE}.${CONTYPE}"
2846
	if [ -f "$OUTPUT" ]
2847
	then
2848
		scriptlog ERROR "Skipping $INPUT. $OUTPUT already exists."
2849
		scriptlog BREAK 
2850
		unset CHANID STARTTIME
2851
		continue
2852
	fi
2853
2854
	INSIZE=$(( `stat -c %s "${INPUT}"` / 1024 ))
2855
	FREESPACE=$(df -k --portability "$INPUT" | awk 'END {print $3}')
2856
	if [ $(( $FREESPACE - $INSIZE )) -lt 10000 ]
2857
	then
2858
		scriptlog ERROR "Stopping due to disk space shortage."
2859
		scriptlog BREAK 
2860
		break
2861
	fi
2862
2863
	[ "$QUICKTIME_MP4" = "YES" ] && X264_OPTS="$X264EXT_OPTS"
2864
2865
	FILEINFO=$(getvidinfo "$INPUT" 0 width height fps scan_type)
2866
	OLDIFS="$IFS"; IFS=":"; set - $FILEINFO; IFS="$OLDIFS"
2867
	INWIDTH="$1"; INHEIGHT="$2"; INFPS="$3"; SCANTYPE="$4";
2868
	if [ "$#" -ne 4 ]
2869
	then
2870
		scriptlog ERROR "Skipping $INPUT. Could not obtain vid format details Width $INWIDTH Height $INHEIGHT fps $INFPS ScanType $SCANTYPE"
2871
		scriptlog BREAK 
2872
		unset CHANID STARTTIME
2873
		continue
2874
	fi
2875
2876
	if [ "$INWIDTH" = 720 -a "$INHEIGHT" = 576 ]
2877
	then
2878
		if [ "$SCANTYPE" = "Progressive" ]
2879
		then
2880
			FORMAT="576p"
2881
		elif [ "$SCANTYPE" = "Interlaced" ]
2882
		then
2883
			FORMAT="576i"
2884
		else
2885
			FORMAT="576i or 576p"
2886
		fi
2887
	elif [ "$INWIDTH" = 720 -a "$INHEIGHT" = 480 ]
2888
	then
2889
		if [ "$SCANTYPE" = "Progressive" ]
2890
		then
2891
			FORMAT="480p"
2892
		elif [ "$SCANTYPE" = "Interlaced" ]
2893
		then
2894
			FORMAT="480i"
2895
		else
2896
			FORMAT="480i or 480p"
2897
		fi
2898
	elif [ "$INWIDTH" = 1280 -a "$INHEIGHT" = 720 ]
2899
	then
2900
		SCANTYPE="Progressive" # Only set if mediainfo available
2901
		FORMAT="720p"
2902
	elif [ "$INWIDTH" = 1440 -a "$INHEIGHT" = 1088 ]
2903
	then
2904
		if [ "$SCANTYPE" = "Progressive" ]
2905
		then
2906
			FORMAT="1080p"
2907
		elif [ "$SCANTYPE" = "Interlaced" ]
2908
		then
2909
			FORMAT="1080i"
2910
		else
2911
			FORMAT="1080i or 1080p"
2912
		fi
2913
	elif [ "$INWIDTH" = 1920 -a "$INHEIGHT" = 1088 ]
2914
	then
2915
		if [ "$SCANTYPE" = "Progressive" ]
2916
		then
2917
			FORMAT="1080p"
2918
		elif [ "$SCANTYPE" = "Interlaced" ]
2919
		then
2920
			FORMAT="1080i"
2921
		else
2922
			FORMAT="1080i or 1080p"
2923
		fi
2924
	else
2925
		FORMAT="Unknown"
2926
	fi
2927
2928
	ASPECTSTR="NA";ASPECTFOUNDIN="NA"
2929
	if [ "$ASPECTINLINE" = "4:3" -o "$ASPECTINLINE" = "16:9" ]
2930
	then
2931
		ASPECTSTR="$ASPECTINLINE"
2932
		ASPECTFOUNDIN="Command Line"
2933
	else
2934
		TMP=$(getaspect "$INPUT")
2935
		ASPECTSTR=$(echo "$TMP" | cut -d',' -f1)
2936
		ASPECTFOUNDIN=$(echo "$TMP" | cut -d',' -f2)
2937
	fi
2938
	if [ "$ASPECTSTR" != "4:3" -a "$ASPECTSTR" != "16:9" ]
2939
	then
2940
		scriptlog ERROR "Skipping $INPUT. Aspect is $ASPECTSTR must be 16:9 or 4:3."
2941
		scriptlog ERROR "If this is a mpg file make sure to set DEFAULTMPEG2ASPECT at top of this script."
2942
		scriptlog BREAK 
2943
		unset CHANID STARTTIME
2944
		continue
2945
	fi
2946
	scriptlog INFO "$FORMAT ${INWIDTH}x${INHEIGHT} $SCANTYPE $ASPECTSTR (Found in $ASPECTFOUNDIN) $INFPS FPS"
2947
2948
	i=0
2949
	OLDTRACKS=$ATRACKS
2950
	ATRACKS=""
2951
	for ATRACK in ${OLDTRACKS//,/ }
2952
	do
2953
		set - ${ATRACK/:/ }
2954
		ATRACK[$i]="$1"
2955
		INALANG[$i]="$2"
2956
		FILEINFO=$(getvidinfo "$INPUT" ${ATRACK[$i]} audio_format audio_sample_rate audio_channels audio_resolution audio_language)
2957
		OLDIFS="$IFS"; IFS=":"; set - $FILEINFO; IFS="$OLDIFS"
2958
		FORMAT="$1"; INARATE[$i]="$2"; CHANNELS[$i]="$3"; MGF_AUDIO_RESOLUTION[$i]="$4"; [ -z "${INALANG[$i]}" ] && INALANG[$i]="$5"
2959
		if [ "$#" -ne 5 ]
2960
		then
2961
			scriptlog ERROR "Skipping $INPUT. Could not obtain aud format details Language ${INALANG[$i]} ARate ${INARATE[$i]} Channels ${CHANNELS[$i]} ASamplingRate ${MGF_AUDIO_RESOLUTION[$i]}"
2962
			scriptlog BREAK 
2963
			unset CHANID STARTTIME
2964
			continue
2965
		fi
2966
		scriptlog INFO "$FORMAT Language ${INALANG[$i]} Audio Rate ${INARATE[$i]} Channels ${CHANNELS[$i]} ASamplingRate ${MGF_AUDIO_RESOLUTION[$i]}"
2967
		[ -n "$ATRACKS" ] && ATRACKS=$ATRACKS,
2968
		ATRACKS=${ATRACKS}${ATRACK[$i]}
2969
		[ "${INALANG[$i]}" != "NA" ] && ATRACKS=${ATRACKS}:${INALANG[$i]}
2970
	
2971
		# Audio resolution
2972
		OGG_AUDIO_RESOLUTION[$i]=""
2973
		FAAC_AUDIO_RESOLUTION[$i]=""
2974
		if echo "${MGF_AUDIO_RESOLUTION[$i]}" | egrep '^[0-9]+$' >/dev/null 2>&1
2975
		then
2976
			OGG_AUDIO_RESOLUTION="--raw-bits=${MGF_AUDIO_RESOLUTION[$i]}"
2977
			FAAC_AUDIO_RESOLUTION="-B ${MGF_AUDIO_RESOLUTION[$i]}"
2978
		fi
2979
	
2980
		# Channel mapping
2981
		FAACCCOPT[$i]=""
2982
		case "${CHANNELS[$i]}" in
2983
			1*|2*|3*|4*) true ;;
2984
			5*|6*) FAACCCOPT[$i]="$FAACCHANCONFIG" ;;
2985
			*) scriptlog ERROR "Audio channels ${CHANNELS[$i]} invalid."
2986
			   scriptlog BREAK 
2987
			   unset CHANID STARTTIME
2988
			   continue
2989
			;;
2990
		esac
2991
		let i=i+1
2992
	done
2993
	scriptlog DEBUG "Audio track definitions: $ATRACKS"
2994
2995
	# Aspect/Scale/Crop opts
2996
	if [ "$ASPECTSTR" = "4:3" ]
2997
	then
2998
		ASPECT=1.333333333
2999
		SCALE=$SCALE43
3000
		if [ "$SCALE" = "NA" ]
3001
		then
3002
			scriptlog ERROR "Skipping $INPUT Aspect 4:3 which is not supported for quality $QLEVEL"
3003
			scriptlog BREAK 
3004
			unset CHANID STARTTIME
3005
			continue
3006
		fi
3007
	elif [ "$ASPECTSTR" = "16:9" ]
3008
	then
3009
		ASPECT=1.77777777778
3010
		SCALE=$SCALE169
3011
	fi
3012
	SCALESTR=$( echo $SCALE | tr ':' 'x' )
3013
	SCALEMEN="scale=${SCALE},"
3014
3015
	OLDIFS="$IFS"; IFS=":"; set - $SCALE; IFS="$OLDIFS"
3016
	OUTWIDTH="$1"; OUTHEIGHT="$2"
3017
	if [ "$OUTWIDTH" = "$INWIDTH" -a "$OUTHEIGHT" = "$INHEIGHT" ]
3018
	then
3019
		CROPSCALE=""
3020
		scriptlog INFO "Input and Output same resolution. crop,scale disabled."
3021
	elif echo "$CROP" | egrep -i 'ON|YES' >/dev/null 2>&1
3022
	then
3023
		if [ "$OUTWIDTH" -gt "$INWIDTH" -o "$OUTHEIGHT" -gt "$INHEIGHT" ]
3024
		then
3025
			scriptlog INFO "Output is a greater scale than input. This is not sensible."
3026
		fi
3027
		CROPX=$CROPSIZE
3028
		CROPY=$CROPSIZE
3029
		CROPW=$(( $INWIDTH - ( 2 * $CROPX ) ))
3030
		CROPH=$(( $INHEIGHT - ( 2 * $CROPY ) ))
3031
		CROPVAL="${CROPW}:${CROPH}:${CROPX}:${CROPY}"
3032
		CROPMEN="crop=${CROPVAL},"
3033
		CROPSCALE="${CROPMEN}${SCALEMEN}"
3034
		scriptlog INFO "Crop to $CROPVAL. Scale to $SCALESTR."
3035
	else
3036
		CROPSCALE="${SCALEMEN}"
3037
		scriptlog INFO "Scale to $SCALESTR."
3038
	fi
3039
3040
	# Filter opts
3041
	OUTFPS="$INFPS" ; MENOUTFPS=""
3042
	POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'"${INVTELECINEFILTER}"',//')
3043
	POSTVIDFILTERS=$(echo ${POSTVIDFILTERS} | sed -e 's/'"${DEINTERLACEFILTER}"',//')
3044
	[ -n "$CHANID" ] && SOURCENAME=$(getsourcename $CHANID)
3045
	# Progressive then skip Deinterlace/Invtelecine
3046
	if echo $INFPS | egrep '^23|^24' >/dev/null 2>&1
3047
	then
3048
		# Keep 23.976 FPS otherwise mencoder will convert to 29.97
3049
		OUTFPS="23.976"
3050
		scriptlog INFO "Input $INFPS FPS. OUTFPS set to $OUTFPS. Deinterlace/Invtelecine filter not needed."
3051
	elif [ "$SCANTYPE" = "Progressive" ]
3052
	then
3053
		scriptlog INFO "$SCANTYPE. Deinterlace/Invtelecine filter not needed."
3054
	# Deinterlace options
3055
	elif echo "$DEINTERLACE" | egrep -i 'ON|YES' >/dev/null 2>&1
3056
	then
3057
		POSTVIDFILTERS="${POSTVIDFILTERS}${DEINTERLACEFILTER},"
3058
		scriptlog INFO "Deinterlace filter added."
3059
		[ "$SCANTYPE" != "Interlaced" ] && scriptlog INFO "If progressive this is wrong use --deinterlace=NO."
3060
		echo "$INFPS" | grep  '^29' >/dev/null 2>&1 &&
3061
			scriptlog INFO "You may need Invtelecine rather than Deinterlace. (--deinterlace=NO --invtelecine=YES)."
3062
	elif [ -n "$SOURCENAME" ] && echo "$DEINTERLACE" | grep -i "$SOURCENAME" >/dev/null 2>&1
3063
	then
3064
		POSTVIDFILTERS="${POSTVIDFILTERS}${DEINTERLACEFILTER},"
3065
		scriptlog INFO "Source $SOURCENAME. Deinterlace filter added."
3066
		[ "$SCANTYPE" != "Interlaced" ] && scriptlog INFO "If progressive this is wrong use --deinterlace=NO."
3067
		echo "$INFPS" | grep  '^29' >/dev/null 2>&1 &&
3068
			scriptlog INFO "You may need Invtelecine rather than Deinterlace. (--deinterlace=NO --invtelecine=YES)."
3069
	# Invtelecine options
3070
	elif echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1 && echo $INFPS | egrep '^24|^25' >/dev/null 2>&1
3071
	then
3072
		# Very unusual to have PAL/DVB telecine video
3073
		scriptlog INFO "Input $INFPS FPS. Invtelecine filter not supported."
3074
	elif echo "$INVTELECINE" | egrep -i 'ON|YES' >/dev/null 2>&1
3075
	then
3076
		POSTVIDFILTERS="${POSTVIDFILTERS}${INVTELECINEFILTER},"
3077
		OUTFPS="23.976"
3078
		scriptlog INFO "Invtelecine filter added."
3079
	fi
3080
	[ "$OUTFPS" = "23.976" ] && MENOUTFPS="-ofps 24000/1001"
3081
	[ -n "$POSTVIDFILTERS" ] && POSTVIDFILTERS="${POSTVIDFILTERS}softskip,"
3082
3083
	# Encoder opts
3084
	# Force avi for videos staying in MythRecord
3085
	if [ "$CONTYPE" = "avi" ] || [ -n "$CHANID" -a -z "$COPYDIR" ]
3086
	then
3087
		if [ "$AVIVID" = "xvid" ]
3088
		then
3089
			VBITRATE=$(calcbitrate $ASPECT $SCALE $XVID_CQ)
3090
			PASSCMD="pass"
3091
			VIDEOCODEC="-ovc xvid -xvidencopts ${XVID_OPTS}:bitrate=${VBITRATE}"
3092
			VIDEXT="xvid"
3093
		elif [ "$AVIVID" = "lavc" ]
3094
		then
3095
			VBITRATE=$(calcbitrate $ASPECT $SCALE $LAVC_CQ)
3096
			PASSCMD="vpass"
3097
			VIDEOCODEC="-ovc lavc -lavcopts ${LAVC_OPTS}:vbitrate=${VBITRATE}"
3098
			VIDEXT="lavc"
3099
		else
3100
			scriptlog ERROR "Skipping $INPUT. Unsupported avi encoder"
3101
			scriptlog BREAK 
3102
			unset CHANID STARTTIME
3103
			continue
3104
		fi
3105
		ABITRATE=$MP3_ABITRATE
3106
		AUDIOCODEC="-oac mp3lame -lameopts vbr=2:br=${ABITRATE}"
3107
		AUDEXT="mp3"
3108
		CONTYPE="avi"
3109
		QUICKTIME_MP4="NO"
3110
		MENOUT1STPASS="-aspect $ASPECT -force-avi-aspect $ASPECTSTR -o /dev/null"
3111
		MENOUTOPT="-aspect $ASPECT -force-avi-aspect $ASPECTSTR -o"
3112
		MENOUTFILE="$OUTPUT"
3113
		MTOPT="--audiotrack ${ATRACKS:0:1}"
3114
	elif [ "$CONTYPE" = "mp4" ]
3115
	then
3116
		VBITRATE=$(calcbitrate $ASPECT $SCALE $X264_CQ)
3117
		AQUAL=$AAC_AQUAL
3118
		PASSCMD="pass"
3119
		VIDEOCODEC="-ovc x264 -x264encopts ${X264_OPTS}:bitrate=${VBITRATE}"
3120
		VIDEXT="h264"
3121
		AUDIOCODEC="-oac copy"
3122
		AUDEXT="aac"
3123
		MENOUT1STPASS="-of rawvideo -o /dev/null"
3124
		MENOUTOPT="-of rawvideo -o"
3125
		MENOUTFILE="${OUTBASE}_video.h264"
3126
	elif [ "$CONTYPE" = "mkv" ]
3127
	then
3128
		VBITRATE=$(calcbitrate $ASPECT $SCALE $X264_CQ)
3129
		if [ "$MKVAUD" = "ogg" ]
3130
		then
3131
			AQUAL=$OGG_AQUAL
3132
			AUDEXT="ogg"
3133
		elif [ "$MKVAUD" = "aac" ]
3134
		then
3135
			AQUAL=$AAC_AQUAL
3136
			AUDEXT="aac"
3137
		else
3138
			scriptlog ERROR "Skipping $INPUT. Unsupported audio encoder"
3139
			scriptlog BREAK 
3140
			unset CHANID STARTTIME
3141
			continue
3142
		fi
3143
		PASSCMD="pass"
3144
		VIDEOCODEC="-ovc x264 -x264encopts ${X264_OPTS}:bitrate=${VBITRATE}"
3145
		VIDEXT="h264"
3146
		AUDIOCODEC="-oac copy"
3147
		MENOUT1STPASS="-of rawvideo -o /dev/null"
3148
		MENOUTOPT="-of rawvideo -o"
3149
		MENOUTFILE="${OUTBASE}_video.h264"
3150
	else
3151
		scriptlog ERROR "Skipping $INPUT. Incorrect video contype selected. $CONTYPE"
3152
		scriptlog BREAK 
3153
		unset CHANID STARTTIME
3154
		continue
3155
	fi
3156
3157
	RETCODE=0
3158
	# Fireoff a background monitoring job to update the job queue details
3159
	[ "$JOBID" -ne 99999999 ] && $CMD --monitor=$JOBID ${$} "$TRANSOP" "$LOGFILE" &
3160
3161
	# Pause boinc
3162
	boinccontrol "suspend"
3163
3164
	#Start time
3165
	ENCSTARTTIME=$(date +%Y-%m-%d\ %H:%M:%S)
3166
	ORIGINALFILESIZE=$(du -h "$INPUT" | cut -f1)
3167
3168
	i=0
3169
	# mp4/mkv have seperate Audio/Video transcodes.
3170
	for ATRACK in ${ATRACKS//,/ }
3171
	do
3172
		ATRACK=${ATRACK:0:1}
3173
		MTOPTS="--audiotrack ${ATRACK}"
3174
		if [ "$AUDEXT" = "aac" ]
3175
		then
3176
			if [ ! -f "${OUTBASE}_audio${ATRACK}.${AUDEXT}" ]
3177
			then
3178
				AENCLINE="faac ${FIFODIR}/audout -P ${FAAC_AUDIO_RESOLUTION[$i]} -R ${INARATE[$i]} -C ${CHANNELS[$i]} ${FAACCCOPT[$i]} -c ${INARATE[$i]} -X -q $AQUAL --mpeg-vers 4 -o ${OUTBASE}_audio$ATRACK.${AUDEXT}"
3179
				scriptlog INFO "Audio Encoder: $AENCLINE."
3180
	
3181
				scriptlog START "Starting $AUDEXT audio trans of $INPUT, track $ATRACK. quality $AQUAL."
3182
				[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] audio pass started"
3183
	
3184
				rm -f "${FIFODIR}"/*out "$TRANSOP" "$MENCODEROP"
3185
				if [ -n "$MTINFILE" ]
3186
				then
3187
					nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" $MTOPTS --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3188
				else
3189
					nice -n 19 mythtranscode --profile autodetect $MTSOURCE $MTOPTS --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3190
				fi
3191
				sleep 10
3192
				# Throw away video
3193
				nice -n 19 dd bs=512k if="${FIFODIR}/vidout" of=/dev/null &
3194
				nice -n 19 faac "${FIFODIR}/audout" -P ${FAAC_AUDIO_RESOLUTION[$i]} -R ${INARATE[$i]} -C ${CHANNELS[$i]} ${FAACCCOPT[$i]} -c ${INARATE[$i]} -X -q $AQUAL --mpeg-vers 4 -o "${OUTBASE}_audio$ATRACK.${AUDEXT}"
3195
				RETCODE=$?
3196
				sleep 10
3197
				if [ $RETCODE -ne 0 ]
3198
				then
3199
					scriptlog ERROR "Skipping $INPUT. Problem with audio pass."
3200
					scriptlog BREAK 
3201
					unset CHANID STARTTIME
3202
					continue
3203
				fi
3204
			else
3205
				scriptlog INFO "Track $ATRACK Audio Encoding already done"
3206
			fi
3207
		elif [ "$AUDEXT" = "ogg" ]
3208
		then
3209
			if [ ! -f "${OUTBASE}_audio$ATRACK.${AUDEXT}" ]
3210
			then
3211
				AENCLINE="oggenc ${OGG_AUDIO_RESOLUTION[$i]} --raw-chan=${CHANNELS[$i]} --raw-rate=${INARATE[$i]} --quality=${AQUAL} -o ${OUTBASE}_audio$ATRACK.${AUDEXT} ${FIFODIR}/audout"
3212
				scriptlog INFO "Audio Encoder: $AENCLINE."
3213
	
3214
				scriptlog START "Starting $AUDEXT audio trans of $INPUT. quality $AQUAL."
3215
				[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] audio pass started"
3216
	
3217
				rm -f "${FIFODIR}"/*out "$TRANSOP" "$MENCODEROP"
3218
				if [ -n "$MTINFILE" ]
3219
				then
3220
					nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" $MTOPTS --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3221
				else
3222
					nice -n 19 mythtranscode --profile autodetect $MTSOURCE $MTOPTS --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3223
				fi
3224
				sleep 10
3225
				# Throw away video
3226
				nice -n 19 dd bs=512k if="${FIFODIR}/vidout" of=/dev/null &
3227
				nice -n 19 oggenc ${OGG_AUDIO_RESOLUTION[$i]} --raw-chan=${CHANNELS[$i]} --raw-rate=${INARATE[$i]} --quality=${AQUAL} -o "${OUTBASE}_audio$ATRACK.${AUDEXT}" "${FIFODIR}/audout"
3228
				RETCODE=$?
3229
				sleep 10
3230
				if [ $RETCODE -ne 0 ]
3231
				then
3232
					scriptlog ERROR "Skipping $INPUT. Problem with audio pass."
3233
					scriptlog BREAK 
3234
					unset CHANID STARTTIME
3235
					continue
3236
				fi
3237
			else
3238
				scriptlog INFO "Track $ATRACK Audio Encoding already done"
3239
			fi
3240
		fi
3241
		let i=i+1
3242
	done
3243
3244
	if [ "$PASS" = "one" ]
3245
	then
3246
		if [ ! -f "$MENOUTFILE" ]
3247
		then
3248
			VENCLINE="mencoder -idx -noskip \
3249
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3250
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3251
			${VIDEOCODEC} \
3252
			${AUDIOCODEC} \
3253
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3254
			$MENOUTOPT $MENOUTFILE"
3255
			scriptlog INFO "Video Encoder: $VENCLINE."
3256
3257
			scriptlog START "Starting $VIDEXT Single video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
3258
			[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Single video pass started."
3259
3260
			rm -f "${FIFODIR}"/*out "$TRANSOP" "$MENCODEROP"
3261
			if [ -n "$MTINFILE" ]
3262
			then
3263
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3264
			else
3265
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3266
			fi
3267
			sleep 10
3268
			nice -n 19 mencoder -idx -noskip \
3269
			"${FIFODIR}/vidout" -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3270
			-audiofile "${FIFODIR}/audout" -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3271
			${VIDEOCODEC} \
3272
			${AUDIOCODEC} \
3273
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3274
			$MENOUTOPT "$MENOUTFILE" | tee -a "$MENCODEROP"
3275
			RETCODE=$?
3276
			sleep 10
3277
		else
3278
			scriptlog INFO "Video Encoding already done"
3279
		fi
3280
	else
3281
		if [ ! -f "$MENOUTFILE" ]
3282
		then
3283
			VENCLINE="mencoder -idx \
3284
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3285
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3286
			${VIDEOCODEC}:${PASSCMD}=1:turbo -passlogfile ${FIFODIR}/2pass.log \
3287
			${AUDIOCODEC} \
3288
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3289
			$MENOUT1STPASS"
3290
			scriptlog INFO "Video Encoder: $VENCLINE."
3291
3292
			scriptlog START "Starting $VIDEXT 1st video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
3293
			[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] 1st video pass started."
3294
3295
			rm -f "${FIFODIR}"/*out "$TRANSOP" "$MENCODEROP"
3296
			if [ -n "$MTINFILE" ]
3297
			then
3298
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3299
			else
3300
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3301
			fi
3302
			sleep 10
3303
			nice -n 19 mencoder -idx \
3304
			"${FIFODIR}/vidout" -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3305
			-audiofile "${FIFODIR}/audout" -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3306
			${VIDEOCODEC}:${PASSCMD}=1:turbo -passlogfile "${FIFODIR}/2pass.log" \
3307
			${AUDIOCODEC} \
3308
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3309
			$MENOUT1STPASS
3310
			RETCODE=$?
3311
			sleep 10
3312
			if [ $RETCODE -ne 0 ]
3313
			then
3314
				scriptlog ERROR "Skipping $INPUT. Problem with 1st video pass of 2."
3315
				scriptlog BREAK 
3316
				unset CHANID STARTTIME
3317
				continue
3318
			fi
3319
		else
3320
			scriptlog INFO "Video Encoding already done"
3321
		fi
3322
3323
		if [ ! -f "$MENOUTFILE" ]
3324
		then
3325
			VENCLINE="mencoder -idx -noskip \
3326
			${FIFODIR}/vidout -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3327
			-audiofile ${FIFODIR}/audout -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3328
			${VIDEOCODEC}:${PASSCMD}=2 -passlogfile ${FIFODIR}/2pass.log \
3329
			${AUDIOCODEC} \
3330
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3331
			$MENOUTOPT $MENOUTFILE"
3332
			scriptlog INFO "Video Encoder: $VENCLINE."
3333
3334
			scriptlog START "Starting $VIDEXT 2nd video pass trans of $INPUT. vbr $VBITRATE abr $ABITRATE."
3335
			[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] 2nd video pass started."
3336
3337
			rm -f "${FIFODIR}"/*out "$TRANSOP" "$MENCODEROP"
3338
			if [ -n "$MTINFILE" ]
3339
			then
3340
				nice -n 19 mythtranscode --profile autodetect $MTINFILE "$MTSOURCE" --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3341
			else
3342
				nice -n 19 mythtranscode --profile autodetect $MTSOURCE --fifodir "$FIFODIR" | tee -a "$TRANSOP" &
3343
			fi
3344
			sleep 10
3345
			nice -n 19 mencoder -idx -noskip \
3346
			"${FIFODIR}/vidout" -demuxer rawvideo -rawvideo w=${INWIDTH}:h=${INHEIGHT}:fps=${INFPS} \
3347
			-audiofile "${FIFODIR}/audout" -audio-demuxer rawaudio -rawaudio rate=${INARATE}:channels=${CHANNELS} \
3348
			${VIDEOCODEC}:${PASSCMD}=2 -passlogfile "${FIFODIR}/2pass.log" \
3349
			${AUDIOCODEC} \
3350
			-vf ${POSTVIDFILTERS}${CROPSCALE}${ENDVIDFILTERS}harddup -sws 7 $MENOUTFPS \
3351
			$MENOUTOPT "$MENOUTFILE" | tee -a "$MENCODEROP"
3352
			RETCODE=$?
3353
			sleep 10
3354
		else
3355
			scriptlog INFO "Video Encoding already done"
3356
		fi
3357
	fi
3358
3359
	if [ $RETCODE -ne 0 ]
3360
	then
3361
		scriptlog ERROR "Skipping $INPUT. Problem with final video pass. $OUTPUT may exist."
3362
		scriptlog BREAK 
3363
		unset CHANID STARTTIME
3364
		continue
3365
	fi
3366
3367
	if [ "$CONTYPE" = "mp4" -o "$CONTYPE" = "mkv" ]
3368
	then
3369
		if [ -f "$CHAPTERFILE" ]
3370
		then
3371
			scriptlog START "Using chapter file $CHAPTERFILE."
3372
		elif [ -n "$CHAPTERDURATION" -a "$CHAPTERDURATION" -gt 0 ]
3373
		then
3374
			scriptlog START "Generating chapter file."
3375
			[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Generating chapter file."
3376
			CHAPTERFILE=$(genchapfile "${OUTBASE}_audio.${AUDEXT}" $CHAPTERDURATION $CONTYPE)
3377
			[ -f "$CHAPTERFILE" ] || scriptlog ERROR "Generating chapter failed."
3378
		fi
3379
		scriptlog START "Joining ${OUTBASE}_video.h264 ${OUTBASE}_audio.${AUDEXT} in $CONTYPE container."
3380
		[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Joining in $CONTYPE container."
3381
		if ! encloseincontainer "$OUTBASE" $OUTFPS $AUDEXT $CONTYPE $ASPECTSTR $ATRACKS "$TITLE" "$CHAPTERFILE"
3382
		then
3383
			scriptlog ERROR "$CONTYPE container Failed for $OUTPUT."
3384
			scriptlog BREAK 
3385
			unset CHANID STARTTIME
3386
			continue
3387
		fi
3388
	fi
3389
3390
	scriptlog START "Checking $OUTPUT."
3391
	[ "$JOBID" -ne 99999999 ] && setjobqueuecomment "$JOBID" "[${$}] Checking result."
3392
	if ! checkoutput "$INPUT" "$OUTPUT" "$MENCODEROP" "$OUTPUTCHECKS"
3393
	then
3394
		mv "$OUTPUT" "${OUTPUT}-SUSPECT"
3395
		scriptlog ERROR "$OUTPUT may be faulty. Saved as ${OUTPUT}-SUSPECT. $INPUT kept."
3396
		scriptlog BREAK 
3397
		unset CHANID STARTTIME
3398
		continue
3399
	fi
3400
3401
	if [ -n "$CHANID" ]
3402
	then
3403
		SEARCHTITLE=$(getsearchtitle "$CHANID" "$STARTTIME")
3404
		is21orless && INETREF=$(lookupinetref "$SEARCHTITLE" "$CHANID" "$STARTTIME") || INETREF="00000000"
3405
		SERIESEPISODE=$(getseriesepisode "$CHANID" "$STARTTIME" "$INETREF")
3406
		FILENAME=$(createfiletitleSEsubtitle "$CHANID" "$STARTTIME" "$SERIESEPISODE")
3407
	else
3408
		FILENAME=$(basename "$OUTPUT" | sed -e 's/\.[am][vkp][iv4]$//')
3409
	fi
3410
3411
	if [ -n "$COPYDIR" ]
3412
	then
3413
		# Is this a good idea?
3414
		#CATEGORY=$(getcategory "$CHANID" "$STARTTIME")
3415
		#[ -n "$CATEGORY" ]
3416
		#then
3417
		#	COPYDIR="${COPYDIR}/${CATEGORY}"
3418
		#fi
3419
		[ -d "$(dirname "$COPYDIR/$FILENAME")" ] || mkdir -p "$(dirname "$COPYDIR/$FILENAME")"
3420
		NEWNAME="$FILENAME"
3421
		while [ -f "${COPYDIR}/${NEWNAME}.${CONTYPE}" ]
3422
		do
3423
			COUNT=$(( ${COUNT:=0} + 1 ))
3424
			NEWNAME="${FILENAME}_${COUNT}"
3425
		done
3426
		FILENAME="${NEWNAME}.${CONTYPE}"
3427
		if cp "$OUTPUT" "${COPYDIR}/${FILENAME}"
3428
		then
3429
			rm -f "$OUTPUT"
3430
			scriptlog SUCCESS "Successful trans. $INPUT trans to ${COPYDIR}/${FILENAME}. $INPUT kept"
3431
			if [ "$QUICKTIME_MP4" = "YES" ]
3432
			then
3433
				OLDFILE="${COPYDIR}/${FILENAME}"
3434
				FILENAME=$(echo "$FILENAME" | sed -e 's/mp4$/mov/')
3435
				mv "$OLDFILE" "${COPYDIR}/${FILENAME}"
3436
			fi
3437
			if is21orless
3438
			then
3439
				MYTHVIDDIR=$(getsetting VideoStartupDir)
3440
				if echo "$COPYDIR" | grep "$MYTHVIDDIR" >/dev/null 2>&1
3441
				then
3442
					createvideometadata "${COPYDIR}/${FILENAME}" "$TITLE" "$ASPECTSTR" "$CHANID" "$STARTTIME" "$INETREF" "$SERIESEPISODE"
3443
				fi
3444
			else
3445
				scriptlog INFO "MythTV V0.22 or greater. Not creating MythVideo entry. Use MythVideo menu"
3446
			fi
3447
			if echo "$DELETEREC" | egrep -i 'ON|YES' >/dev/null 2>&1 && [ "$FINALEXIT" -eq 0 ]
3448
			then
3449
				scriptlog INFO "Deleting recording."
3450
				deleterecording "$CHANID" "$STARTTIME"
3451
			fi
3452
			NEWFILESIZE=$(du -h "${COPYDIR}/${FILENAME}" | cut -f1)
3453
		else
3454
			scriptlog ERROR "Successful trans but copy to ${COPYDIR}/${FILENAME} bad. $INPUT trans to $OUTPUT. $INPUT kept"
3455
		fi
3456
	else
3457
		if [ -n "$CHANID" ]
3458
		then
3459
			scriptlog INFO "Updating MythRecord db to $OUTPUT."
3460
			updatemetadata "$OUTPUT" "$CHANID" "$STARTTIME"
3461
			# mythcommflag --rebuild does not work correctly for avi files.
3462
			# Without this you can't edit files, but with it seeks don't work correctly.
3463
			#scriptlog INFO "Rebuilding seektable for $OUTPUT."
3464
			#mythcommflag --chanid "$CHANID" --starttime "$STARTTIME" --rebuild >/dev/null
3465
			rm -f "${INPUT}.png"
3466
		fi
3467
		if [ "$DEBUG" = "ON" -o "$SAVENUV" = "ON" ]
3468
		then
3469
			mv "$INPUT" "${INPUT}OK-DONE"
3470
			scriptlog SUCCESS "Successful trans to $OUTPUT. $INPUT moved to ${INPUT}OK-DONE."
3471
		else
3472
			rm -f "$INPUT"
3473
			scriptlog SUCCESS "Successful trans to $OUTPUT. $INPUT removed."
3474
		fi
3475
		NEWFILESIZE=$(du -h "$OUTPUT" | cut -f1)
3476
	fi
3477
	# End time
3478
	ENCENDTIME=$(date +%Y-%m-%d\ %H:%M:%S)
3479
	logtranstime "$ENCSTARTTIME" "$ENCENDTIME" "$ORIGINALFILESIZE" "$NEWFILESIZE"
3480
	scriptlog BREAK 
3481
	recall
3482
	unset CHANID STARTTIME
3483
done
3484
exit $FINALEXIT
3485
3486
3487
#STARTNUVINFO
3488
#!/usr/bin/perl
3489
# $Date: 2010/10/09 21:06:19 $
3490
# $Revision: 1.61 $
3491
# $Author: mythtv $
3492
#
3493
#  mythtv::nuvinfo.pm
3494
#
3495
#   exports one routine:  nuv_info($path_to_nuv)
3496
#   This routine inspects a specified nuv file, and returns information about
3497
#   it, gathered either from its nuv file structure
3498
#
3499
# Auric grabbed from nuvexport and Modified. Thanks to the nuvexport guys, I never would have been able to work this out
3500
#
3501
# 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
3502
3503
# Byte swap a 32-bit number from little-endian to big-endian
3504
    sub byteswap32 {
3505
       # Read in a 4-character string
3506
       my $in = shift;
3507
       my $out = $in;
3508
3509
       if ($Config{'byteorder'} == 4321) {
3510
           substr($out, 0, 1) = substr($in, 3, 1);
3511
           substr($out, 3, 1) = substr($in, 0, 1);
3512
           substr($out, 1, 1) = substr($in, 2, 1);
3513
           substr($out, 2, 1) = substr($in, 1, 1);
3514
       }
3515
3516
       return $out;
3517
    }
3518
3519
# Byte swap a 64-bit number from little-endian to big-endian
3520
    sub byteswap64 {
3521
       # Read in a 8-character string
3522
       my $in = shift;
3523
       my $out = $in;
3524
3525
       if ($Config{'byteorder'} == 4321) {
3526
           substr($out, 4, 4) = byteswap32(substr($in, 0, 4));
3527
           substr($out, 0, 4) = byteswap32(substr($in, 4, 4));
3528
       }
3529
3530
       return $out;
3531
    }
3532
3533
# Opens a .nuv file and returns information about it
3534
    sub nuv_info {
3535
        my $file = shift;
3536
        my(%info, $buffer);
3537
    # open the file
3538
        open(DATA, $file) or die "Can't open $file:  $!\n\n";
3539
    # Read the file info header
3540
        read(DATA, $buffer, 72);
3541
    # Byte swap the buffer
3542
        if ($Config{'byteorder'} == 4321) {
3543
            substr($buffer, 20, 4) = byteswap32(substr($buffer, 20, 4));
3544
            substr($buffer, 24, 4) = byteswap32(substr($buffer, 24, 4));
3545
            substr($buffer, 28, 4) = byteswap32(substr($buffer, 28, 4));
3546
            substr($buffer, 32, 4) = byteswap32(substr($buffer, 32, 4));
3547
            substr($buffer, 40, 8) = byteswap64(substr($buffer, 40, 8));
3548
            substr($buffer, 48, 8) = byteswap64(substr($buffer, 48, 8));
3549
            substr($buffer, 56, 4) = byteswap32(substr($buffer, 56, 4));
3550
            substr($buffer, 60, 4) = byteswap32(substr($buffer, 60, 4));
3551
            substr($buffer, 64, 4) = byteswap32(substr($buffer, 64, 4));
3552
            substr($buffer, 68, 4) = byteswap32(substr($buffer, 68, 4));
3553
        }
3554
    # Unpack the data structure
3555
        ($info{'finfo'},          # "NuppelVideo" + \0
3556
         $info{'version'},        # "0.05" + \0
3557
         $info{'width'},
3558
         $info{'height'},
3559
         $info{'desiredheight'},  # 0 .. as it is
3560
         $info{'desiredwidth'},   # 0 .. as it is
3561
         $info{'pimode'},         # P .. progressive, I .. interlaced  (2 half pics) [NI]
3562
         $info{'aspect'},         # 1.0 .. square pixel (1.5 .. e.g. width=480: width*1.5=720 for capturing for svcd material
3563
         $info{'fps'},
3564
         $info{'videoblocks'},    # count of video-blocks -1 .. unknown   0 .. no video
3565
         $info{'audioblocks'},    # count of audio-blocks -1 .. unknown   0 .. no audio
3566
         $info{'textsblocks'},    # count of text-blocks  -1 .. unknown   0 .. no text
3567
         $info{'keyframedist'}
3568
            ) = unpack('Z12 Z5 xxx i i i i a xxx d d i i i i', $buffer);
3569
    # Perl occasionally over-reads on the previous read()
3570
        seek(DATA, 72, 0);
3571
    # Read and parse the first frame header
3572
        read(DATA, $buffer, 12);
3573
    # Byte swap the buffer
3574
        if ($Config{'byteorder'} == 4321) {
3575
            substr($buffer, 4, 4) = byteswap32(substr($buffer, 4, 4));
3576
            substr($buffer, 8, 4) = byteswap32(substr($buffer, 8, 4));
3577
        }
3578
        my ($frametype,
3579
            $comptype,
3580
            $keyframe,
3581
            $filters,
3582
            $timecode,
3583
            $packetlength) = unpack('a a a a i i', $buffer);
3584
    # Parse the frame
3585
        die "Illegal nuv file format:  $file\n\n" unless ($frametype eq 'D');
3586
    # Read some more stuff if we have to
3587
        read(DATA, $buffer, $packetlength) if ($packetlength);
3588
    # Read the remaining frame headers
3589
        while (12 == read(DATA, $buffer, 12)) {
3590
        # Byte swap the buffer
3591
            if ($Config{'byteorder'} == 4321) {
3592
                substr($buffer, 4, 4) = byteswap32(substr($buffer, 4, 4));
3593
                substr($buffer, 8, 4) = byteswap32(substr($buffer, 8, 4));
3594
            }
3595
        # Parse the frame header
3596
            ($frametype,
3597
             $comptype,
3598
             $keyframe,
3599
             $filters,
3600
             $timecode,
3601
             $packetlength) = unpack('a a a a i i', $buffer);
3602
        # Read some more stuff if we have to
3603
            read(DATA, $buffer, $packetlength) if ($packetlength);
3604
        # Look for the audio frame
3605
            if ($frametype eq 'X') {
3606
            # Byte swap the buffer
3607
                if ($Config{'byteorder'} == 4321) {
3608
                    substr($buffer, 0, 4)  = byteswap32(substr($buffer, 0, 4));
3609
                    substr($buffer, 12, 4) = byteswap32(substr($buffer, 12, 4));
3610
                    substr($buffer, 16, 4) = byteswap32(substr($buffer, 16, 4));
3611
                    substr($buffer, 20, 4) = byteswap32(substr($buffer, 20, 4));
3612
                    substr($buffer, 24, 4) = byteswap32(substr($buffer, 24, 4));
3613
                    substr($buffer, 28, 4) = byteswap32(substr($buffer, 28, 4));
3614
                    substr($buffer, 32, 4) = byteswap32(substr($buffer, 32, 4));
3615
                    substr($buffer, 36, 4) = byteswap32(substr($buffer, 36, 4));
3616
                    substr($buffer, 40, 4) = byteswap32(substr($buffer, 40, 4));
3617
                    substr($buffer, 44, 4) = byteswap32(substr($buffer, 44, 4));
3618
                    substr($buffer, 48, 4) = byteswap32(substr($buffer, 48, 4));
3619
                    substr($buffer, 52, 4) = byteswap32(substr($buffer, 52, 4));
3620
                    substr($buffer, 56, 4) = byteswap32(substr($buffer, 56, 4));
3621
                    substr($buffer, 60, 8) = byteswap64(substr($buffer, 60, 8));
3622
                    substr($buffer, 68, 8) = byteswap64(substr($buffer, 68, 8));
3623
                }
3624
                my $frame_version;
3625
                ($frame_version,
3626
                 $info{'video_type'},
3627
                 $info{'audio_type'},
3628
                 $info{'audio_sample_rate'},
3629
                 $info{'audio_bits_per_sample'},
3630
                 $info{'audio_channels'},
3631
                 $info{'audio_compression_ratio'},
3632
                 $info{'audio_quality'},
3633
                 $info{'rtjpeg_quality'},
3634
                 $info{'rtjpeg_luma_filter'},
3635
                 $info{'rtjpeg_chroma_filter'},
3636
                 $info{'lavc_bitrate'},
3637
                 $info{'lavc_qmin'},
3638
                 $info{'lavc_qmax'},
3639
                 $info{'lavc_maxqdiff'},
3640
                 $info{'seektable_offset'},
3641
                 $info{'keyframeadjust_offset'}
3642
                 ) = unpack('ia4a4iiiiiiiiiiiill', $buffer);
3643
            # Found the audio data we want - time to leave
3644
                 last;
3645
            }
3646
        # Done reading frames - let's leave
3647
            else {
3648
                last;
3649
            }
3650
        }
3651
    # Close the file
3652
        close DATA;
3653
    # Make sure some things are actually numbers
3654
        $info{'width'}  += 0;
3655
        $info{'height'} += 0;
3656
    # HD fix
3657
        if ($info{'height'} == 1080) {
3658
            $info{'height'} = 1088;
3659
        }
3660
    # Make some corrections for myth bugs
3661
        $info{'audio_sample_rate'} = 44100 if ($info{'audio_sample_rate'} == 42501 || $info{'audio_sample_rate'} =~ /^44\d\d\d$/);
3662
    # NEIL Don't know why he hard set it?
3663
    #    $info{'aspect'} = '4:3';
3664
    # Cleanup
3665
        $info{'aspect'}   = aspect_str($info{'aspect'});
3666
        $info{'aspect_f'} = aspect_float($info{'aspect'});
3667
    # Return
3668
        return %info;
3669
    }
3670
3671
    sub aspect_str {
3672
        my $aspect = shift;
3673
    # Already in ratio format
3674
        return $aspect if ($aspect =~ /^\d+:\d+$/);
3675
    # European decimals...
3676
        $aspect =~ s/\,/\./;
3677
    # Parse out decimal formats
3678
        if ($aspect == 1)          { return '1:1';    }
3679
        elsif ($aspect =~ m/^1.3/) { return '4:3';    }
3680
        elsif ($aspect =~ m/^1.7/) { return '16:9';   }
3681
        elsif ($aspect == 2.21)    { return '2.21:1'; }
3682
    # Unknown aspect
3683
        print STDERR "Unknown aspect ratio:  $aspect\n";
3684
        return $aspect.':1';
3685
    }
3686
3687
    sub aspect_float {
3688
        my $aspect = shift;
3689
    # European decimals...
3690
        $aspect =~ s/\,/\./;
3691
    # In ratio format -- do the math
3692
        if ($aspect =~ /^\d+:\d+$/) {
3693
            my ($w, $h) = split /:/, $aspect;
3694
            return $w / $h;
3695
        }
3696
    # Parse out decimal formats
3697
        if ($aspect eq '1')        { return  1;     }
3698
        elsif ($aspect =~ m/^1.3/) { return  4 / 3; }
3699
        elsif ($aspect =~ m/^1.7/) { return 16 / 9; }
3700
    # Unknown aspect
3701
        return $aspect;
3702
    }
3703
3704
my %info = nuv_info($ENV{'NUVINFOFILE'});
3705
my $c = 0;
3706
foreach my $key (split(' ', $ENV{'NUVINFOPROPS'})) {
3707
	($info{$key}) or $info{$key} = "NA";
3708
	($c++ < 1) and print "$info{$key}" or print ":$info{$key}";
3709
}
3710
print "\n";
3711
#ENDNUVINFO
3712
3713
###########################################################################################################
3714
License Notes:
3715
--------------
3716
3717
This software product is licensed under the GNU General Public License
3718
(GPL). This license gives you the freedom to use this product and have
3719
access to the source code. You can modify this product as you see fit
3720
and even use parts in your own software. If you choose to do so, you
3721
also choose to accept that a modified product or software that use any
3722
code from mythnuv2mkv.sh MUST also be licensed under the GNU General Public
3723
License.
3724
3725
In plain words, you can NOT sell or distribute mythnuv2mkv.sh, a modified
3726
version or any software product based on any parts of mythnuv2mkv.sh as a
3727
closed source product. Likewise you cannot re-license this product and
3728
derivates under another license other than GNU GPL.
3729
3730
See also the article, "Free Software Matters: Enforcing the GPL" by
3731
Eben Moglen. http://emoglen.law.columbia.edu/publications/lu-13.html
3732
###########################################################################################################