· 4 years ago · Dec 05, 2020, 12:00 AM
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.
14readonly DEFAULTMPEG2ASPECT="${DEFAULTMPEG2ASPECT-NA}" # 4:3 or 16:9
15# Log directory
16readonly 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
18readonly MPLAYER_ERROR_COUNT="${MPLAYER_ERROR_COUNT-8}"
19# Path to your mysql.txt file
20readonly MYSQLTXT="${MYSQLTXT-}"
21# What to separate title, subtitle etc. with
22readonly SEP="${SEP-,}"
23# What (if at all) to replace spaces with
24readonly TR="${TR-_}"
25# printf(episode_number)
26readonly EPISODE_FORMAT="${EPISODE_FORMAT-E%02d}"
27# printf(formatted_episode, season_number)
28readonly SEASON_FORMAT="${SEASON_FORMAT-S%2\$02d%1\$s }"
29# printf(title, formatted_season_episode)
30readonly TITLE_FORMAT="${TITLE_FORMAT-%s %s}"
31# printf(filename, date)
32readonly DATE_FORMAT="${DATE_FORMAT-%s [%s]}"
33# RegEx for matching season/episode numbers
34readonly EPISODE_RE="${EPISODE_RE-^S[0-9]+E[0-9]+ $}"
35# Chapter marks every X minutes
36CHAPTERDURATION="${CHAPTERDURATION-0}"
37# Crop input
38CROP="${CROP-ON}" # ON | OFF, can also change with --crop argument
39CROPSIZE="${CROPSIZE-8}"
40# Delete recording after successful transcode. Only for transcode out of MythRecording. (Actually just sets to high priority autoexpire.)
41DELETEREC="${DELETEREC-OFF}" # ON | OFF, can also change with --deleterec argument
42# Include denoise filter
43DENOISE="${DENOISE-OFF}" # ON | OFF, can also change with --denoise argument
44# Include deblock filter
45DEBLOCK="${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"
48DEINTERLACE="${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.
51INVTELECINE="${INVTELECINE-OFF}" # ON | OFF, can also change with --invtelecine argument.
52# number passes
53PASS="${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)
55THREADS="${THREADS-1}"
56# avi encoder lavc or xvid
57AVIVID="${AVIVID-lavc}" # lavc | xvid, can also change with --contype=avi,xvid argument
58# container
59CONTYPE="${CONTYPE-mkv}" # mkv | mp4 | avi, can also change with --contype argument or name of script.
60# mkv audio encoder aac or ogg
61MKVAUD="${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
64ATRACKS="${ATRACKS-0}" # n[:lng][,m[:lng]]..., can also change with --audiotracks
65# add your own filters if you want
66POSTVIDFILTERS="${POSTVIDFILTERS-}" #must include , at end
67ENDVIDFILTERS="${ENDVIDFILTERS-}" #must include , at end
68# Disable some output checks. Can have multiple. e.g. OUTPUTCHECKS="NOSIZERATIO,NOSCAN"
69OUTPUTCHECKS="${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
71readonly BOINCPASSWD="${BOINCPASSWD-}"
72# Use mediainfo if available to identify video properties.
73USEMEDIAINFO="${USEMEDIAINFO-TRUE}" # TRUE or FALSE
74# default quality profile
75QUALITY="${QUALITY-med}"
76
77#
78PATH=~mythtv/bin:${HOME}/bin:$PATH:/usr/local/bin
79# these variables will be recalled, if temporarily overriden, on every file change
80RECALL="ASPECTINLINE DENOISE POSTVIDFILTERS DEBLOCK DEINTERLACE INVTELECINE CROP CROPSIZE DELETEREC CHAPTERDURATION \
81CHAPTERFILE COPYDIR CONTYPE QUICKTIME_MP4 MKVAUD AVIVID PASS SCALE43 SCALE169 LAVC_CQ LAVC_OPTS XVID_CQ XVID_OPTS \
82MP3_ABITRATE X264_CQ X264EXT_OPTS X264_OPTS AAC_AQUAL OGG_AQUAL ATRACKS TITLE SUBTITLE"
83# these variables will be clean on every file change
84CLEAN="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.
91readonly CMAPFILE="$(dirname ${0})/mythnuv2mkv-category-mappings"
92if [ -f "$CMAPFILE" ]
93then
94 . "$CMAPFILE"
95else
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"
110fi
111
112##########################################################################################################
113USAGE='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 ...
114Must have either --chanid=chanid and --starttime=starttime or a plain filename. These can be mixed. e.g. -
115mythnuv2mkv.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
172Logs to /var/tmp/mythnuv2mkvPID.log and to database if "log MythTV events to database" is enabled in mythtv.
173Cutlists are always honored.
174Sending the mythnuv2mkv.sh process a USR1 signal will cause it to stop after completing the current file.
175e.g. kill -s USR1 PID
176If run as a Myth Job, you can find the PID in the System Status Job Queue or Log Entries screens as [PID]
177
178Typical usage.
179
180Myth User Job
181PATH/mythnuv2mkv.sh --jobid=%JOBID% --copydir /mythvideodirectory --chanid=%CHANID% --starttime=%STARTTIME%
182This will convert nuv to mkv and copy it to /mythvideodirectory.
183This 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.
184NOTE. System Status Job Queue screen and the Job Queue Comments field in MythWeb always report job Completed Successfully even if it actually failed.
185
186Myth Video
187Record program
188mythrename.pl --link --format %T-%S --underscores --verbose (mythrename.pl is in the mythtv contrib directory
189cp from your mythstore/show_names/PROGRAM to your MythVideo directory
190use video manager to add imdb details
191nuv files work fine in MythVideo, but if you need to convert them to mkv/mp4/avi, or need to reduce their size
192run mythnuv2mkv.sh MythVideo_file.nuv
193
194Myth Recording
195Record program
196run mythnuv2mkv.sh --findtitle="title name"
197get chanid and starttime
198run mythnuv2mkv.sh --chanid=chanid --starttime=starttime
199NOTE 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.
200NOTE You cannot play a mkv/mp4 file in Myth Recording.
201I would in general recommend leaving everything in Myth Recording as nuv.
202
203You 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
237Version: $Revision: 1.91 (beta) $ $Date: 2011/03/23 01:13:12 $
238'
239REQUIREDAPPS='
240Required Applications
241For all contypes
242mythtranscode.
243perl
244mplayer http://www.mplayerhq.hu/design7/news.html
245mencoder http://www.mplayerhq.hu/design7/news.html
246wget http://www.gnu.org/software/wget/
247ImageMagick http://www.imagemagick.org/script/index.php
248For avi
249mp3lame http://www.mp3dev.org
250xvid http://www.xvid.org/
251For mkv and mp4 contypes
252x264 http://www.videolan.org/developers/x264.html
253faac http://sourceforge.net/projects/faac/
254faad2 http://sourceforge.net/projects/faac/
255For mkv contype
256mkvtoolnix http://www.bunkus.org/videotools/mkvtoolnix/
257For mkv,ogg contype
258vorbis-tools http://www.vorbis.com/
259For mp4 contype
260MP4Box http://gpac.sourceforge.net/index.php
261'
262HELP=${USAGE}${REQUIREDAPPS}
263
264##### Pre Functions ###########################################
265preversioncheck() {
266local PRODUCT="$1"
267local 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###########################################################
292readonly AVIREQPROGS="mencoder mythtranscode mplayer perl wget convert"
293readonly AVIREQLIBS="libmp3lame.so libxvidcore.so"
294readonly MP4REQPROGS="mencoder mythtranscode mplayer perl wget convert faac MP4Box"
295readonly MP4REQLIBS="libx264.so"
296readonly MKVREQPROGS="mencoder mythtranscode mplayer perl wget convert faac oggenc mkvmerge"
297readonly MKVREQLIBS="libx264.so"
298###########################################################
299readonly DENOISEFILTER="hqdn3d"
300readonly DEBLOCKFILTER="pp7"
301readonly DEINTERLACEFILTER="pp=fd"
302readonly INVTELECINEFILTER="pullup"
303readonly FAACCHANCONFIG="-I 5,6"
304readonly TE_SCALE43="NA" # NA
305readonly ST_SCALE43="NA" # NA
306readonly FE_SCALE43="640:480" # 1.32
307readonly FS_SCALE43="768:576" # 1.32
308readonly HIGH_SCALE43=528:400 # 1.32
309readonly MED_SCALE43=512:384 # 1.333
310readonly LOW_SCALE43=448:336 # 1.333
311readonly TE_SCALE169="1920:1088" # 1.778
312readonly ST_SCALE169="1280:720" # 1.778
313readonly FE_SCALE169="848:480" # 1.766
314readonly FS_SCALE169="1024:576" # 1.778
315readonly HIGH_SCALE169=656:368 # 1.783
316readonly MED_SCALE169=624:352 # 1.773
317readonly LOW_SCALE169=592:336 # 1.762
318# Default
319SCALE43=$MED_SCALE43
320SCALE169=$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 ####
335readonly HIGH_LAVC_CQ=0.22
336readonly MED_LAVC_CQ=0.21
337readonly LOW_LAVC_CQ=0.20
338readonly 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"
343readonly MED_LAVC_OPTS="$HIGH_LAVC_OPTS"
344readonly LOW_LAVC_OPTS="$HIGH_LAVC_OPTS"
345#### AVI xvid mpeg4 ####
346readonly HIGH_XVID_CQ=0.22
347readonly MED_XVID_CQ=0.21
348readonly LOW_XVID_CQ=0.20
349readonly HIGH_XVID_OPTS="threads=${THREADS}:quant_type=mpeg:me_quality=6:chroma_me:chroma_opt:trellis:hq_ac:vhq=4:bvhq=1"
350readonly MED_XVID_OPTS="$HIGH_XVID_OPTS"
351readonly LOW_XVID_OPTS="$HIGH_XVID_OPTS"
352#### AVI lavc/xvid mp3 ####
353readonly HIGH_MP3_ABITRATE=256
354readonly MED_MP3_ABITRATE=192
355readonly LOW_MP3_ABITRATE=128
356#### MP4/MKV h.263/aac,ogg ####
357readonly HIGH_X264_CQ=0.15
358readonly MED_X264_CQ=0.14
359readonly LOW_X264_CQ=0.13
360preversioncheck "libx264" # Sets BPYRAMID & NOBPYRAMID & FORCECFR
361# H.264 Extended profile (quicktime) level set in QLEVEL
362readonly 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"
367readonly MED_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
368readonly LOW_X264EXT_OPTS="$HIGH_X264EXT_OPTS"
369# H.264 High profile level set in QLEVEL
370readonly 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"
375readonly MED_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
376readonly LOW_X264HIGH_OPTS="$HIGH_X264HIGH_OPTS"
377# AAC
378readonly HIGH_AAC_AQUAL=100
379readonly MED_AAC_AQUAL=90
380readonly LOW_AAC_AQUAL=80
381# OGG
382readonly HIGH_OGG_AQUAL=6
383readonly MED_OGG_AQUAL=5
384readonly LOW_OGG_AQUAL=4
385# Defaults
386LAVC_OPTS=$MED_LAVC_OPTS
387LAVC_CQ=$MED_LAVC_CQ
388XVID_OPTS=$MED_XVID_OPTS
389XVID_CQ=$MED_XVID_CQ
390MP3_ABITRATE=$MED_MP3_ABITRATE
391AAC_AQUAL=$MED_AAC_AQUAL
392OGG_AQUAL=$MED_OGG_AQUAL
393X264EXT_OPTS="level_idc=31:$MED_X264EXT_OPTS"
394X264_OPTS="level_idc=31:$MED_X264HIGH_OPTS"
395X264_CQ=$MED_X264_CQ
396if echo "$(basename $0)" | grep -i 'mkv' >/dev/null 2>&1
397then
398 CONTYPE="mkv"
399 QUICKTIME_MP4="NO"
400elif echo "$(basename $0)" | grep -i 'mp4' >/dev/null 2>&1
401then
402 CONTYPE="mp4"
403 QUICKTIME_MP4="NO"
404elif echo "$(basename $0)" | grep -i 'mov' >/dev/null 2>&1
405then
406 #TODO. Not working yet don't use mov
407 CONTYPE="mp4"
408 QUICKTIME_MP4="YES"
409elif echo "$(basename $0)" | grep -i 'avi' >/dev/null 2>&1
410then
411 CONTYPE="avi"
412 QUICKTIME_MP4="NO"
413fi
414###########################################################
415# ON or OFF
416# debug mode
417DEBUG="OFF"
418DEBUGSQL="OFF"
419DEBUGSG="OFF"
420# Print INFO messages
421INFO="ON"
422# Save(via a rename) or delete nuv file. Only for transcode back into MythRecording.
423SAVENUV="OFF"
424
425[ "$DEBUGSQL" = "ON" ] && DEBUG="ON"
426
427##### Functions ###########################################
428scriptlog() {
429local LEVEL="$1"
430shift
431local PRIORITY
432local HIGHLIGHTON
433local 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
482versioncheck() {
483local PRODUCT="$1"
484local VER
485local MAJ
486local MIN
487local 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
511chkreqs() {
512local REQPROGS="$1"
513local REQLIBS="$2"
514local TMP
515local 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
538calcbitrate() {
539local ASPECT=$1
540local SCALE=$2
541local CQ=$3
542local W
543local H
544local 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
551getsetting() {
552local VALUE="$1"
553local HOST=$(hostname)
554local 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.
570getstoragegroupdirs() {
571 mysql --batch --skip-column-names --user="${DBUserName}" --password="${DBPassword}" -h "${DBHostName}" "${DBName}" <<-EOF
572 select distinct dirname from storagegroup;
573 EOF
574}
575
576hascutlist() {
577local CHANID="$1"
578local STARTTIME="$2"
579local 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
588getrecordfile() {
589local CHANID="$1"
590local STARTTIME="$2"
591local DEBUGSG="$3"
592local DATA
593local DATALINE
594local RECFILE
595local 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
635getsourcename() {
636local 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
643gettitle() {
644local CHANID="$1"
645local 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
652getsubtitle() {
653local CHANID="$1"
654local 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
661findchanidstarttime() {
662local 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
668updatemetadata() {
669local NEW="$1"
670local CHANID="$2"
671local STARTTIME="$3"
672local 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
689createvideocover() {
690local CFDIR="$1"
691local FILENAME="$2"
692local ASPECT="$3"
693local THDIR="${FIFODIR}/THDIR"
694local THUMB_NAME=$(basename "$FILENAME" | sed -e 's/\.[am][vkp][iv4]$/\.png/')
695local THUMB_PATH="${CFDIR}/${THUMB_NAME}"
696local CURWD
697local 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
717getsearchtitle() {
718local CHANID="$1"
719local STARTTIME="$2"
720local TI
721local ST
722local 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
734lookupinetref() {
735# : is used to separate Title and SubTitle in SEARCHTITLE
736local SEARCHTITLE="$1"
737local CHANID="$2"
738local STARTTIME="$3"
739local IMDBCMD
740local IMDBRES
741local IMDBSTR=""
742# INETREF will be 00000000 if not found
743local INETREF=00000000
744local SERIES
745local EPISODE
746local YEAR
747local 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
801getseriesepisode() {
802local CHANID="$1"
803local STARTTIME="$2"
804local INETREF="$3"
805local DATA
806local 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
839createfiletitleSEsubtitle() {
840local CHANID="$1"
841local STARTTIME="$2"
842local SE="$3"
843local DATA
844local T
845local 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
856is21orless() {
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
864is24ormore() {
865 local DATA=$(mythtranscode --audiotrack 2>&1)
866 echo "$DATA" | grep -q 'Unknown option: --audiotrack' && return 1 || return 0
867}
868
869createvideometadata() {
870local FILENAME="$1"
871local TITLE="$2"
872local ASPECT="$3"
873local CHANID="$4"
874local STARTTIME="$5"
875local INETREF="$6"
876# SE may be null
877local SE="$7"
878local DIRECTOR="Unknown"
879#local PLOT="None"
880local PLOT="$(getplot $CHANID $STARTTIME)"
881local MOVIERATING="NR"
882#local YEAR=1895
883local YEAR="$(getyear $CHANID $STARTTIME)"
884local USERRATING=0
885local RUNTIME=0
886local COVERFILE="No Cover"
887local GENRES=""
888local COUNTRIES=""
889local CATEGORY=""
890local CFDIR=$(getsetting "VideoArtworkDir")
891local TI
892local ST
893local IMDBCMD
894local IMDBSTR
895local GTYPE
896local TH
897local SE
898local S
899local E
900local WHERE
901local TMP
902local IDS
903local VIDID
904local 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
1186hasvideometadata() {
1187local FILENAME="$1"
1188local 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
1196deleterecording() {
1197local CHANID="$1"
1198local 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
1205insertmythlogentry() {
1206local PRIORITY="$1"
1207local LEVEL="$2"
1208local PID="$3"
1209local DETAILS="$(echo $4 | tr -d '[:cntrl:]' | tr -d '[\\\"]')"
1210local DATETIME=$(date '+%Y%m%d%H%M%S')
1211local 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
1224getjobqueuecmds() {
1225local JOBID="$1"
1226local DATA
1227local JQCMDSTR[0]="RUN"
1228local JQCMDSTR[1]="PAUSE"
1229local JQCMDSTR[2]="RESUME"
1230local JQCMDSTR[4]="STOP"
1231local 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
1239setjobqueuecmds() {
1240local JOBID="$1"
1241local CMDSSTR="$2"
1242local 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
1260getjobqueuestatus() {
1261local JOBID="$1"
1262local DATA
1263local JQSTATUSSTR[0]="UNKNOWN"
1264local JQSTATUSSTR[1]="QUEUED"
1265local JQSTATUSSTR[2]="PENDING"
1266local JQSTATUSSTR[3]="STARTING"
1267local JQSTATUSSTR[4]="RUNNING"
1268local JQSTATUSSTR[5]="STOPPING"
1269local JQSTATUSSTR[6]="PAUSED"
1270local JQSTATUSSTR[7]="RETRY"
1271local JQSTATUSSTR[8]="ERRORING"
1272local JQSTATUSSTR[9]="ABORTING"
1273local JQSTATUSSTR[256]="DONE"
1274local JQSTATUSSTR[272]="FINISHED"
1275local JQSTATUSSTR[288]="ABORTED"
1276local JQSTATUSSTR[304]="ERRORED"
1277local 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
1285setjobqueuestatus() {
1286local JOBID="$1"
1287local STATUSSTR="$2"
1288local 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
1318getjobqueuecomment() {
1319local JOBID="$1"
1320local 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
1326setjobqueuecomment() {
1327local JOBID="$1"
1328local 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.
1337getchannelaspect() {
1338local CHANID=$1
1339local 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.
1358querycardaspect() {
1359local CHANID=$1
1360local 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
1379getaviinfomidentify() {
1380local FILE="$1"
1381local ATRACK="$2"
1382shift 2
1383local PROPS="$@"
1384local MPOP
1385local TMP
1386local p
1387local RES
1388local ASPECTFOUNDIN
1389local width=1 ; infokey[1]="ID_VIDEO_WIDTH"
1390local height=2 ; infokey[2]="ID_VIDEO_HEIGHT"
1391local fps=3 ; infokey[3]="ID_VIDEO_FPS"
1392local audio_sample_rate=4 ; infokey[4]="ID_AUDIO_RATE"
1393local audio_channels=5 ; infokey[5]="ID_AUDIO_NCH"
1394local aspect=6 ; infokey[6]="ID_VIDEO_ASPECT"
1395local length=7 ; infokey[7]="ID_LENGTH"
1396local video_format=8 ; infokey[8]="ID_VIDEO_FORMAT"
1397local 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
1465getaviinfomediainfo() {
1466local FILE="$1"
1467local ATRACK="$2"
1468shift
1469local PROPS="$@"
1470local TMP
1471local p
1472local RES
1473local 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
1563getnuvinfo() {
1564export NUVINFOFILE="$1"
1565shift
1566export NUVINFOPROPS="$@"
1567 PROPS=$(sed -n '/^#STARTNUVINFO$/,/#ENDNUVINFO/p' $CMD | perl)
1568 echo "$PROPS"
1569}
1570
1571getvidinfo() {
1572local FILE="$1"
1573local ATRACK="$2"
1574shift 2
1575local PROPS="$@"
1576local 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
1591getaspect() {
1592local FILE="$1"
1593local 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
1600getlengthffmpeg() {
1601FILE="$1"
1602local 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
1607getlength() {
1608FILE="$1"
1609local 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
1625setsave() {
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
1639recall() {
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
1662setaspect() {
1663 setsave ASPECTINLINE "$1" "$2"
1664}
1665
1666setdenoise() {
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
1678setdeblock() {
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
1690setdeinterlace() {
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
1700setinvtelecine() {
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
1710setcrop() {
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
1726setdeleterec() {
1727 setsave DELETEREC "$(echo "$1" | tr '[a-z]' '[A-Z]')" "$2"
1728 scriptlog INFO "Delete Recording set to $DELETEREC."
1729}
1730
1731setchapterduration() {
1732 setsave CHAPTERDURATION "$1" "$2"
1733 scriptlog INFO "Chapter Duration set to $CHAPTERDURATION."
1734}
1735
1736setchapterfile() {
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
1747setcopydir() {
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
1759setcontype() {
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
1833setpass() {
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
1848setquality() {
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
1957setaudiotracks() {
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
1984parsetitle() {
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
2033stoptime() {
2034local STARTSECS=$1
2035local MAXRUNHOURS=$2
2036local CURSECS
2037local 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
2044checkoutput() {
2045local INPUT="$1"
2046local OUTPUT="$2"
2047local MENCODERRES="$3"
2048local OUTPUTCHECKS="$4"
2049local VIDFOR
2050local OUTSIZE
2051local INSIZE
2052local RAT
2053local SCANOUTFILE
2054local LCOUNT
2055local ECOUNT
2056local INFRAMES
2057local OUTFRAMES
2058local 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
2148getcategory() {
2149local CHANID="$1"
2150local STARTTIME="$2"
2151local 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
2160getplot() {
2161local CHANID="$1"
2162local STARTTIME="$2"
2163local 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
2172getyear() {
2173local CHANID="$1"
2174local STARTTIME="$2"
2175local 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
2188genchapfile() {
2189local FILE="$1"
2190local DURATION=$(( $2 * 60 ))
2191local CONTYPE="$3"
2192local CHAPTERFILE="${FIFODIR}/chapters.txt"
2193local LENGTH
2194local CHAPTER
2195local COUNT
2196local CHAPMINS
2197local CHAPHOURS
2198local 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
2232encloseincontainer() {
2233local OUTBASE="$1"
2234local FPS="$2"
2235local AUDEXT="$3"
2236local CONTYPE="$4"
2237local ASPECT="$5"
2238local ATRACKS="$6"
2239local TITLE="$7"
2240local CHAPTERFILE="$8"
2241local CHAPTERS=""
2242local RET
2243local MKVTRACKS
2244local MP4TRACKS
2245local MKVTITLE
2246local TRACK
2247local 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
2438logtranstime () {
2439local START=$1
2440local END=$2
2441local ORIGINALFILESIZE=$3
2442local 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
2451boinccontrol() {
2452local 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
2466cleanup() {
2467local SIG="$1"
2468local JOBID="$2"
2469local OUTPUT="$3"
2470local OUTBASE
2471local 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
2514MYSQLLIST="$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"
2515for m in $MYSQLLIST
2516do
2517 [ -f $m ] && . $m && break
2518done
2519if [ -z "$DBName" ]
2520then
2521 echo "Can't find mysql.txt. Change MYSQLTXT variable at top of script with your mysql.txt path"
2522 exit 1
2523fi
2524
2525##### BG Monitor #####################################
2526# This will be fired off in background to update the jobqueue comment and process stop/pause/resume requests.
2527if echo "$1" | egrep -i '\-\-monitor=' >/dev/null 2>&1
2528then
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
2628fi
2629
2630##### Globals ########################################
2631readonly CMD="$0"
2632readonly LOGFILE="${LOGBASEDIR}/mythnuv2mkv${$}.log"
2633readonly FIFODIR="${LOGBASEDIR}/mythnuv2mkv${$}"
2634readonly MENCODEROP="${FIFODIR}/mencoder.op"
2635readonly TRANSOP="${FIFODIR}/transcode.op"
2636readonly STOPREQUEST="${FIFODIR}/STOPREQUEST"
2637if ! tty >/dev/null 2>&1
2638then
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
2647else
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`
2653fi
2654# DBLOGGING is reverse to shell true/false
2655DBLOGGING=0
2656OUTPUT=""
2657JOBID=99999999
2658FINALEXIT=0
2659STARTSECS="NA"
2660MAXRUNHOURS="NA"
2661MKVMERGE251BUG="NO"
2662
2663##### Main ###########################################
2664if echo "$1" | egrep -i '\-help|\-usage|\-\?' >/dev/null 2>&1
2665then
2666 echo "$HELP"
2667 exit 1
2668fi
2669
2670if [ "$CONTYPE" = "mkv" ]
2671then
2672 chkreqs "$MKVREQPROGS" "$MKVREQLIBS" || exit 1
2673 versioncheck "mkvmerge"
2674elif [ "$CONTYPE" = "mp4" ]
2675then
2676 chkreqs "$MP4REQPROGS" "$MP4REQLIBS" || exit 1
2677elif [ "$CONTYPE" = "avi" ]
2678then
2679 chkreqs "$AVIREQPROGS" "$AVIREQLIBS" || exit 1
2680fi
2681if ! versioncheck "convert"
2682then
2683 scriptlog INFO "The program \"convert\" does not appear to be the ImageMagick one. This will only affect coverfile creation."
2684fi
2685
2686trap 'cleanup ABRT "$JOBID" "$OUTPUT"' INT ABRT
2687trap 'touch $STOPREQUEST ; scriptlog INFO "USR1 received. Will stop after current file completes."' USR1
2688trap 'cleanup EXIT "$JOBID"' EXIT
2689mkdir -m 775 -p "${LOGBASEDIR}" >/dev/null 2>&1 || scriptlog ERROR "Could not create ${LOGBASEDIR}"
2690mkdir -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
2698for INPUT in "$@"
2699do
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
3483done
3484exit $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
3704my %info = nuv_info($ENV{'NUVINFOFILE'});
3705my $c = 0;
3706foreach my $key (split(' ', $ENV{'NUVINFOPROPS'})) {
3707 ($info{$key}) or $info{$key} = "NA";
3708 ($c++ < 1) and print "$info{$key}" or print ":$info{$key}";
3709}
3710print "\n";
3711#ENDNUVINFO
3712
3713###########################################################################################################
3714License Notes:
3715--------------
3716
3717This software product is licensed under the GNU General Public License
3718(GPL). This license gives you the freedom to use this product and have
3719access to the source code. You can modify this product as you see fit
3720and even use parts in your own software. If you choose to do so, you
3721also choose to accept that a modified product or software that use any
3722code from mythnuv2mkv.sh MUST also be licensed under the GNU General Public
3723License.
3724
3725In plain words, you can NOT sell or distribute mythnuv2mkv.sh, a modified
3726version or any software product based on any parts of mythnuv2mkv.sh as a
3727closed source product. Likewise you cannot re-license this product and
3728derivates under another license other than GNU GPL.
3729
3730See also the article, "Free Software Matters: Enforcing the GPL" by
3731Eben Moglen. http://emoglen.law.columbia.edu/publications/lu-13.html
3732###########################################################################################################