#!/usr/bin/python """ Update cache or -n (--noupdate) and search cache for rec_ids: surlatablo.py -q search_pattern Update cache with new recording and deletions surlatablo.py Search for recordings and convert them surlatablo.py -n -q search_pattern -c Use option --help for detailed usage. """ SLT_GLOBAL = {} SLT_GLOBAL['PGM_VERSION'] = '0.7' # Sur la Tablo (on the Tablo) SLT_GLOBAL['PGM_NAME'] = 'surlatablo' # License SLT_GLOBAL['PGM_LICENSE'] = 'GPLv2' # Configuration file # You can override option variables below by putting your into # this file. SLT_GLOBAL['CONF'] = '~/surlatablo.conf' ### PROGRAM LOCATIONS # Replace with full path location of your programs FFMPEG = '/usr/bin/ffmpeg' CCEXTRACTOR = '/usr/local/bin/ccextractor' ### IMPORTANT LOCAL SETTINGS SURLATABLO_ROOT = '/SurLaTablo' # Cache db goes here TABLO_IPS = ['127.0.0.1'] # Should we detect? # Use a python list of Tablo IPs. LOCAL_TIMEZONE = 'US/Central' # Your current timezone NOZEROTV = True # Substitutes se for when # season or episode are zero (for meta_type TV) # Also sets episode title import os if (os.name == 'nt'): GIF_FONTFILE = 'C:/Windows/Fonts/airial.ttf' # Populates dynamic meta var ${gif_fontfile} else: GIF_FONTFILE = '/usr/share/fonts/truetype/DejaVuSans.ttf' # Populates dynamic meta var ${gif_fontfile} ### CONF FILE PROCESSING # You can override and/or augment anything above this line using # the contents of the config file. # # Open and read the conf data into a variable so we can exec it # again later. So that substitutions can be done to config items # after this line. # try: if (os.path.isfile(os.path.expanduser(SLT_GLOBAL['CONF']))): with open(os.path.expanduser(SLT_GLOBAL['CONF']),'r') as f: confdata = f.read() exec confdata except: pass ### DIRECTORY AND FILE CREATION PATTERNS # Patterns for output handling by meta_type (e.g. TV, Sports, Movie, Manual) # Patterns can contain meta information made by this program using # ${meta-name}. Just like TabloTV, this programs metadata is non-uniform # by media type (aka meta_type) # BASE_DIRS={'Default':'./${meta_type}', 'Sports':'./${meta_type}/${sport_type}/Season ${season_number}', 'TV':'./${meta_type}/${Eseries}/Season ${season_number}', 'Movie':'./${meta_type}/${Etitle} (${release_year})' } # Everything but the final extension of the final transcoded file. See TRANSCODER_OPTS last element. FILENAME_PATS={'Default':'${Etitle}', 'TV':'${Eseries} - s${plex_season_number}e${plex_episode_number} - ${Etitle}', 'Sports':'${sport_type} - s${plex_season_number}e${plex_episode_number} - ${Etitle}', 'Movie':'${Etitle} (${release_year})' } ############################################################################### # BE CAREFUL ABOUT MODS TO OPTIONS BELOW ############################################################################### # CHANGELOG # # 0.7 - # 1. -E, -S, now gerneralized and long formats renamed to --episode and --season. # These can now be used to force season and episode data in a made up way # for handling TV by series name values where no season/episode meta data # was provided. # e.g. -S Gidget::1 -E Gidget::1 # When queried, converting, this arranges the series matches for Gidget # by original air date and numbers season as "1" and episodes starting # at "1" and auto-incrementing. # The behavior for making up meta data for Sports shows has not changed. # 2. Removed some extraneous debug prints. # 3. Added the -B option to allow converting/processing of shows that are # stuck on the Tablo in a non-"finished" state. Not sure what causes this. # Some say it happens when things go "bad", but I think I've seen this # just randomly. Anyhow, if you have stuck shows that always say they # are *RECORDING/BUSY*, this option will allow you to ignore that # (use with caution... don't ignore shows that you know are really # recording, and if you do, avoid converting them until they are # truly done recording). # 4. Fixed bug, sort_title was not working. You will want to remove your # SURLATABLO_ROOT/ cache files and regenerate. # 5. Added -s (--sortkeys) option to allow you to specify what metakeys to # to sort by (default is sort by lair_date descending). Warning: this # is also a filter. Records that do not have all the metakeys specified # will not be output. For example if you have -q . (everything) and -s # series, only TV shows will be shown since they are the only records # containing series. # 6. Query format (-Q) may now specify urls. In which case they are templated # (that is, metakey substitutions are done). # There are two formats. url('location1','location2',...) and # URL('location1','location2',...). The second variant, URL, forces # metakey substitution on each url prior to inclusion. If the resource # scheme begins with '1' (e.g. 1http://...) then include that resource # only once for all matches. Resource schemes allowed are (http: and file:, # some others might work...) # 0.6 - # 1. Fix surlatablo.conf bug, put back trap around it, read into a variable # so that it can be exec'd twice, before major options and after. # 2. Changed meaning of -O (offset) to be offset for whatever matches, just # and offset value. The default setting is to apply the options['liveoffset'] # value to Live shows (from new meta type qualifiers_). # 3. Successfully tested on OSX. Not really a "bug", just a statement. # 0.5 - # Quick fix to correct Eseries bug. # 0.4 - # 1. You may now have a SLT_GLOBAL['CONF'] file (defaults to homedir # surlatablo.conf) which can be used to override the configuration variables. # This way you won't have to keep editing the source file for local site # changes. # 2. TV shows with season 0 and episode 0 (e.g. News) will now default # to se and Unknown titles will default # to Episode - --. You can # disable this by setting NOZERTV = False in your .conf file (see #1). # original_air_date cannot be used for this because quite often it is wrong. # 3. Pathnames for output files are now santized for Windows. # 4. surlatablo.py now takes arugments beyond switches which are to specify # the transcodes to do on the downloaded data. Default if not present is # just Mp4. You can override the default by setting in you .conf file: # TRANSCODER_DEFAULT = [ 'Mp4', 'Gif', etc. ] # You can specify on the command like: # surlatablo.py .... Mp4 Gif Json # or # surlatablo.py .... +Gif +Json # The '+' means in addition to the TRANSCODER_DEFAULT values. # Use '-t' option to see brief description of available transcoders. # 5. Options --wcrop (-w) and --cropformat (-W) have been removed. Create and # use a new TRANSCODER_OPTS definition for this. # 6. You can now use --keepdir @ to say you want to save the .ts and .srt file # in the output directory with the other files. # 7. New predefined TRANSCODER_OPTS have been added, created. (see -t option) # a. Mp4 - (the norm) to create a passthrough .mp4 # b. Gif - create short duration animated gif # c. Flash - create an .flv # d. HardSubs - (assumes use of -C) to embed subitles directly in .mp4 # e. Shrink - create a more compressed .mp4 # f. Json - create .json file containing SurLaTablo meta information for program # g. Null - used mainly to say "no transcode", for times when you want to use # --keepdir @ to output and save just the .ts and (optionally) .srt # h. ... (more) # 8. Replace sanitizeFilename with sltSanitize for dynamic meta type strings # like Etitle, Eseries, essentially things that could be used in path and filenames. # Special dynamic variable Efriendly_title2 is a two line escaped string for # internal ffmpeg option use (see Gif). # 9. Bug fixes.... etc... # #Sat Jan 17 14:24:17 CST 2015 # 0.3 - New metatype, sort_title, which is the title minus leading # a/an/the article. Added a sanitizeFilename function, mainly for # Windows. # #Thu Jan 15 00:00:26 CST 2015 # 0.2 - Defined some timezone stuff for when there is no pytz. Doesn't handle # everything. Handle escapes like \n, \t in -Q. Check for ability to # create SURLATABLO_ROOT and exit with a message instead of fail with stack # trace. New meta-type, friendly_title, added to make it easier to use # friendly_title~='Series - s01' for easy season selection. ### COMMAND OPTIONS ### TRANSCODER options # Allowed functions that can be called as transcoder. TRANSCODER_FUNCS = [ 'shutil.copyfile', 'dumpJson', 'print' ] # Default transcode(s) to provide if none provided TRANSCODER_DEFAULT = [ 'Mp4' ] # The allowed transcoders # All data options here need to be strings. TRANSCODER_OPTS = { 'Mp4': { 'help': [ 'Standard pass through conversion of video and audio from Tablo .ts to .mp4.' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'subtitlefile': [ '-f', 'srt', '-i', '${srt_filename}' ], 'options': [ '-bsf:a', 'aac_adtstoasc', '-c:v', 'copy', '-c:a', 'copy' ], 'subtitleoptions': [ '-c:s', 'mov_text', '-metadata:s:s:0', 'language=${lang3}' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'metadata': [], 'ext': [ '.mp4' ] }, 'Mp4W': { 'help': [ 'Crop a 4:3 480i channel presentation of a 16:9 widescreen movie.' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'subtitlefile': [ '-f', 'srt', '-i', '${srt_filename}' ], 'options': [ '-bsf:a', 'aac_adtstoasc', '-vf', 'crop=720:360:0:60', '-c:a', 'copy' ], 'subtitleoptions': [ '-c:s', 'mov_text', '-metadata:s:s:0', 'language=${lang3}' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'metadata': [], 'ext': [ '-w.mp4' ] }, 'Gif': { 'help': [ 'Create an short animated Gif' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-ss', '${gifstart}', '-i', '${ts_filename}', '-t', '${gifduration}' ], 'options': [ '-loop', '0', '-r', '${gifrate}', '-s', '${gifsize}', '-vf', 'drawtext=fontfile=${gif_fontfile}:text=\'${Efriendly_title2}\':fontcolor=white@1.0:fontsize=30:x=10:y=40' ], 'ext': [ '.gif' ] }, 'Flash': { 'help': [ 'Create an flash .flv file' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'options': [ '-ab', '56', '-ar', '44100', '-r', '25', '-qmin', '3', '-qmax', '6', '-s', '320x240' ], 'ext': [ '.flv' ] }, 'HardSubs': { 'help': [ 'For use with -C, burn the subtitles directly into the video of the .mp4' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'options': [], 'subtitleoptions': [ '-vf', 'subtitles=\'${srt_filename}\'' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'ext': [ '-hs.mp4' ] }, 'Shrink': { 'help': [ 'Create a smaller .mp4 file.' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'subtitlefile': [ '-f', 'srt', '-i', '${srt_filename}' ], 'options': [ '-crf', '25' ], 'subtitleoptions': [ '-c:s', 'mov_text', '-metadata:s:s:0', 'language=${lang3}' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'metadata': [], 'ext': [ '-sm.mp4' ] }, # This is here more or less as an example, normally you would do this with -k @ # An example of using a python libray module function instead of an executable. 'Ts': { 'help': [ 'Testing, do not use. Use --keepdir @ instead.' ], 'command': [ 'shutil.copyfile' ], 'inputfile': [ '${ts_filename}' ], 'ext': [ '.ts' ] }, # This is so that if we transcode, and then go back an delete off of the Tablo, # we can have a way to preserve the meta data for the program. # This is an example of calling a global procedure defined here. 'Json': { 'help': [ 'Save json meta data into .json file.' ], 'command': [ 'dumpJson' ], 'inputfile': [ '"${rec_id}": ${json}' ], 'ext': [ '.json' ], 'skip_ts': [ 'True' ] }, 'Null': { 'help': [ 'To specify no transcodes. Useful when combined with --keepdir @.' ], 'command': [ 'print' ], 'ext': [ '.always' ] }, # Slow 'Glow': { 'help': [ 'Apply the Frei04 Glow affect to video.' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'subtitlefile': [ '-f', 'srt', '-i', '${srt_filename}' ], 'options': [ '-vf', 'frei0r=glow:0.5' ], 'subtitleoptions': [ '-c:s', 'mov_text', '-metadata:s:s:0', 'language=${lang3}' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'metadata': [], 'ext': [ '-glow.mp4' ] }, # Slow 'h265': { 'help': [ 'Product an HEVC h265 .mp4 file.' ], 'command': [ FFMPEG ], 'threads': [ '-threads', '0' ], 'inputfile': [ '-i', '${ts_filename}' ], 'subtitlefile': [ '-f', 'srt', '-i', '${srt_filename}' ], 'options': [ '-bsf:a', 'aac_adtstoasc', '-c:v', 'libx265', '-preset', 'ultrafast', '-x265-params', 'crf=28', '-c:a', 'copy' ], 'subtitleoptions': [ '-c:s', 'mov_text', '-metadata:s:s:0', 'language=${lang3}' ], 'audiooptions': [ '-metadata:s:a:0', 'language=${lang3}' ], 'metadata': [], 'ext': [ '-h265.mp4' ] } } ### CCEXTRACTOR options CCEXTRACTOR_OPTS = { 'Default': { 'command': [ CCEXTRACTOR ], 'inputfile': [ '${ts_filename}' ], 'options': [ '--gui_mode_reports' ], 'outputfile': [ '-o', '${srt_filename}' ] } } ### OTHER MODIFIERS # Tablo url templates TABLO_SEGS='http://${tablo_ip}:18080/pvr/${rec_id}/segs' TABLO_REC_IDS='http://${tablo_ip}:18080/plex/rec_ids' TABLO_CHAN_IDS='http://${tablo_ip}:18080/plex/ch_ids' TABLO_CHAN_INFO='http://${tablo_ip}:18080/plex/ch_info?id={}' TABLO_REC_INFO='http://${tablo_ip}:18080/plex/rec_info?id={}' ### OPTION DEFAULTS options = { 'keepdir': '', 'ccoffset': '', 'liveoffset': '4', 'noclobber' : True, 'ccaption' : False, 'ccaptionopts' : CCEXTRACTOR_OPTS['Default'], 'srtsubtitle' : '', 'srtmovtext' : '', 'gifstart' : '00:01:45', 'gifduration' : '10', 'gifrate' : '10', 'gifsize' : '320x200' } ### CONF FILE PROCESSING, part2 # To solve some chicken egg scenarios, exec the config file data again. try: exec confdata except: pass # Mapping of 2char lang to 3char lang. # Assumes that Gracenote/Tribune data even knows about all of these. lang3 = { 'ab': 'abk', 'aa': 'aar', 'af': 'afr', 'ak': 'aka', 'sq': 'sqi', 'am': 'amh', 'ar': 'ara', 'an': 'arg', 'hy': 'hye', 'as': 'asm', 'av': 'ava', 'ae': 'ave', 'az': 'aze', 'bm': 'bam', 'ba': 'bak', 'eu': 'eus', 'be': 'bel', 'bn': 'ben', 'bh': 'bih', 'bi': 'bis', 'bs': 'bos', 'br': 'bre', 'bg': 'bul', 'my': 'mya', 'ca': 'cat', 'ch': 'cha', 'ce': 'che', 'ny': 'nya', 'zh': 'zho', 'cv': 'chv', 'kw': 'cor', 'co': 'cos', 'cr': 'cre', 'hr': 'hrv', 'cs': 'ces', 'da': 'dan', 'dv': 'div', 'nl': 'nld', 'dz': 'dzo', 'en': 'eng', 'eo': 'epo', 'et': 'est', 'ee': 'ewe', 'fo': 'fao', 'fj': 'fij', 'fi': 'fin', 'fr': 'fra', 'ff': 'ful', 'gl': 'glg', 'ka': 'kat', 'de': 'deu', 'el': 'ell', 'gn': 'grn', 'gu': 'guj', 'ht': 'hat', 'ha': 'hau', 'he': 'heb', 'hz': 'her', 'hi': 'hin', 'ho': 'hmo', 'hu': 'hun', 'ia': 'ina', 'id': 'ind', 'ie': 'ile', 'ga': 'gle', 'ig': 'ibo', 'ik': 'ipk', 'io': 'ido', 'is': 'isl', 'it': 'ita', 'iu': 'iku', 'ja': 'jpn', 'jv': 'jav', 'kl': 'kal', 'kn': 'kan', 'kr': 'kau', 'ks': 'kas', 'kk': 'kaz', 'km': 'khm', 'ki': 'kik', 'rw': 'kin', 'ky': 'kir', 'kv': 'kom', 'kg': 'kon', 'ko': 'kor', 'ku': 'kur', 'kj': 'kua', 'la': 'lat', 'lb': 'ltz', 'lg': 'lug', 'li': 'lim', 'ln': 'lin', 'lo': 'lao', 'lt': 'lit', 'lu': 'lub', 'lv': 'lav', 'gv': 'glv', 'mk': 'mkd', 'mg': 'mlg', 'ms': 'msa', 'ml': 'mal', 'mt': 'mlt', 'mi': 'mri', 'mr': 'mar', 'mh': 'mah', 'mn': 'mon', 'na': 'nau', 'nv': 'nav', 'nd': 'nde', 'ne': 'nep', 'ng': 'ndo', 'nb': 'nob', 'nn': 'nno', 'no': 'nor', 'ii': 'iii', 'nr': 'nbl', 'oc': 'oci', 'oj': 'oji', 'cu': 'chu', 'om': 'orm', 'or': 'ori', 'os': 'oss', 'pa': 'pan', 'pi': 'pli', 'fa': 'fas', 'pl': 'pol', 'ps': 'pus', 'pt': 'por', 'qu': 'que', 'rm': 'roh', 'rn': 'run', 'ro': 'ron', 'ru': 'rus', 'sa': 'san', 'sc': 'srd', 'sd': 'snd', 'se': 'sme', 'sm': 'smo', 'sg': 'sag', 'sr': 'srp', 'gd': 'gla', 'sn': 'sna', 'si': 'sin', 'sk': 'slk', 'sl': 'slv', 'so': 'som', 'st': 'sot', 'es': 'spa', 'su': 'sun', 'sw': 'swa', 'ss': 'ssw', 'sv': 'swe', 'ta': 'tam', 'te': 'tel', 'tg': 'tgk', 'th': 'tha', 'ti': 'tir', 'bo': 'bod', 'tk': 'tuk', 'tl': 'tgl', 'tn': 'tsn', 'to': 'ton', 'tr': 'tur', 'ts': 'tso', 'tt': 'tat', 'tw': 'twi', 'ty': 'tah', 'ug': 'uig', 'uk': 'ukr', 'ur': 'urd', 'uz': 'uzb', 've': 'ven', 'vi': 'vie', 'vo': 'vol', 'wa': 'wln', 'cy': 'cym', 'wo': 'wol', 'fy': 'fry', 'xh': 'xho', 'yi': 'yid', 'yo': 'yor', 'za': 'zha', 'zu': 'zul' } def detailedHelp(): helpstring = """ ${PGM_NAME} ${PGM_VERSION} ${PGM_LICENSE} FIRST THINGS ------------ Edit this program and change the values for (near top of file): # Location of your ffmpeg program (optional if you won't convert to mp4) FFMPEG = '/usr/bin/ffmpeg' # Location of your ccextractor program (optional) CCEXTRACTOR = '/usr/local/bin/ccextractor' # Location directory where meta db caches go SURLATABLO_ROOT = '/SurLaTablo' # List of your Tablo IPs, this program does not auto detect today TABLO_IPS = ['192.168.1.73'] UPDATE AND SEARCH ----------------- Update cache db (need metadata db to do anything) (typically you do this first, first run will take a bit) surlatablo.py Update and search db surlatablo.py --query Green\ Acres Do not update cache, just search db (note matches Green Acres anywhere in the metadata) surlatablo.py --noupdate --query Green\ Acres Search db by metadata # Find all for TV series called Green Acres surlatablo.py --noupdate --query series~=Green\ Acres # Find all Sports records surlatablo.py --noupdate --query meta_type~=Sports Use a query format string to change output # Find all TV shows and user a query format for output # (note --queryformat will not do anything combined with --convert) surlatablo.py --noupdate --query meta_type~=TV --queryformat '${lair_date}\t${rec_id}\t${series}\t${title}' Display full TabloTV metadata for a specific recording id. # (note --rec_id can be used with --convert) surlatablo.py --noupdate --rec_id 28191 Note: You can easily force a full refresh of local cached data by removing the files at SULATABLO_ROOT/Tablo_IP/* CONVERT OR PREVIEW CONVERT (ADD SUBTITLES/CC, MP4 METADATA) ----------------------------------------------------------------- Locate a particular recording, convert with close captioning done as a subtitle. Sample interative output also shown. surlatablo.py --noupdate --query Fuji\ falls --convert --ccaption --clobber Working on: [./TV/McHale's Navy/Season 3/McHale's Navy - s03e15 - Fuji's Big Romance.mp4] Retrieving Tablo Data (28191): [####################] 100% Extracting CC as Subtitle: [####################] 100% Transcoding: [####################] 100% Locate all sports and use default season of game_year and use supplied episode start number by sport_type. Defaulting starting with episode number 1 for unspecified types. surlatablo.py --noupdate --query meta_type~=Sports -E "NFL Football::3,NBA Basketball::5,1" --convert Use the --debug (probably misnamed) to show what surlatablo.py would do, but don't do it (option to be combined with --convert) surlatablo.py --noupdate --query Fuji\ falls --convert --ccaption --clobber --debug [ ./TV/McHale's Navy/Season 3/McHale's Navy - s03e15 - Fuji's Big Romance.mp4 ] [ http://192.168.1.73:18080/pvr/28191/segs -> /tmp/TabloE1_zkh.ts] ['/usr/local/bin/ccextractor', '/tmp/TabloE1_zkh.ts', '--gui_mode_reports', '-o', '/tmp/TabloZdkhvf.srt'] ['/usr/bin/ffmpeg', '-i', '/tmp/TabloE1_zkh.ts', '-f', 'srt', '-i', '/tmp/TabloZdkhvf.srt', '-bsf:a', 'aac_adtstoasc', '-c:v', 'copy', '-c:a', 'copy', '-c:s', 'mov_text', '-metadata:s:s:0', 'language=eng', '-metadata:s:a:0', 'language=eng', '-metadata', "title=Fuji's Big Romance", '-metadata', 'date=1964-12-25', '-metadata', 'network=Antenna', '-metadata', "album=McHale's Navy", '-metadata', "show=McHale's Navy", '-metadata', 'genre=Sitcom', '-metadata', 'episode_id=s03e15', '-metadata', "synopsis=Fuji falls in love with a native chief's daughter.", '-metadata', "description=Fuji falls in love with a native chief's daughter.", '-metadata', "comment=Fuji falls in love with a native chief's daughter.", '-y', "./TV/McHale's Navy/Season 3/McHale's Navy - s03e15 - Fuji's Big Romance.mp4"] Note: Better, full output of an actual --convert can be captured simply be redirecting output to a file instead of to screen/terminal. Useful for when things aren't working (bugs in the software). Note: Program uses Python tempfile functions. To adjust your temporary directory place: tempfile.tempdir = '/path-to/my-tempdir' For other notes on how Python finds your temporary file location, see Python documentation. MORE EXAMPLES ------------- Find all Mister Ed episodes and convert them using the Default transoding plug a short animated Gif preview: surlatablo.py -n -q series~='Mister Ed' -C -c +Gif BASIC CONVERT OPTIONS (for use with --convert) --------------------- --ccaption = Pull closed captioning off of Tablo recording and convert it to subtitle format for inclusion with final transcode. --clobber = By default, this program will not convert if the target end result filename already exists. --keepdir = Instead of deleting intermediate temporary files (e.g. the Tablo .ts file, the subtitle .srt file), keep them here. If keepdir is @, files will go to the destination directory for the final transcoded files and be named like --filename. ADVANCED CONVERT OPTIONS ------------------------ As with query formats, you may use metadata keys inside of the paths here. --episode = Format of the form: [::|::] Use episode_number starting with start_number and incrementing by one for every match. Different start_numbers can be specified for the different sport_types. --season = Format of the form: [::|::] Override using the game_date and use supplied season_number as the season for the sporting event, a different season can be specified by each sport_type. --basedir = Format of the form: ::,.. Base directory location for final converted mp4 file based on meta_type. Predefines are (BASE_DIRS): Default = ./${meta_type} (e.g. ./Movie, ./Manual) Sports = ./${meta_type}/${sport_type}/Season ${season_number} (e.g. ./Sports/NFL Football/Season 2014) (remember, you can override the season_number for Sports on the command line with -S) TV = ./${meta_type}/${Eseries}/Season ${season_number} --filename = Format of the form: ::,... (minus the file extension) Predefines are (FILENAME_PATS): Default = ${Etitle} TV = ${Eseries} - s${plex_season_number}e${plex_episode_number} - ${Etitle} Sports = ${sport_type} - s${plex_season_number}e${plex_episode_number} - ${Etitle} Movie = ${Etitle} (${release_year}) Note: The Default applies only in cases where there is no meta_type match. So if we wanted to override the location for a TV show. We could override with, --basedir TV::. --filename TV::MyOwnFilename The output then would simply be placed at ./MyOwnFilename.mp4. If we want Movies to stored inside of directory instead of flat inside of the Default basedir, we could use, --basedir Movie::./${meta_type}/${Etitle} (${release_year}) You can alter the values of BASE_DIRS and FILENAME_PATS in this program to make your own "default" settings persistent. COMMAND LINE SWITCH SUMMARY WITH SHORTCUTS ------------------------------------------ -h, --help = Print this very long help. -t, --transcodehelp = Summary of valid transcode arguments -v, --version = Print this program version. -d, --debug = Turn on "debug" output, which is really just a show without execution flag for --convert. -c, --convert = Attempt to transcode a matching query set or --rec_id value. -C, --ccaption = Extract subtitle .srt file from closed captioning and insert subtitle stream into final ouput file. -y, --clobber = Overwrite final destination file. Normally, program exits if final output file exists. -n, --noupdate = Do not process new or deletions off Tablo unit, just go off existing cached data. -i, --rec_id = Show TabloTV/Tribune full metadata for supplied id. -k, --keepdir = Keep temporary files used in --convert at this directory location. Use @ to keep with transcoded files. -q, --query = Query the meta db, in particular format can be of the form metakey~=Value. -b, --basedir = Comma separted list of basedir format patterns, [ = Formatted pattern to produce final name (without extension). -S, --season = Format is [::|::]season-number instead of using game_year|lair_date_month. -E, --set_episode = Format is [::|::]episode-number. -Q, --queryformat = Format is re string (matches across full record) or re string patterned automatically. -O, --ccoffset