transcode and export script

For discussion related to MythTV which doesn't belong in another forum.

Moderator: Forum Moderators

Post Reply
daraden
Senior
Posts: 172
Joined: Tue Feb 23, 2016 7:33 am
United States of America

transcode and export script

Post by daraden » Mon May 23, 2016 6:08 pm

This script is loosely based on the script here https://www.mythtv.org/wiki/Transcode_Mpeg2_to_H264
This script allows transcoding recordings to mkv or mp4 with closed captions as a subtitle track, and embedded Metadata. if the recording has a cut list commercials will be removed(script preforms cutting to avoid issues found with mythtranscode).
It also features an export function for exporting to external media servers in a Kodi compatible format.
The script can be run with Mythtv without the need for additional software but will use ffmpeg if installed
Metadata and export file naming uses Mythtv database

usage- relpace original recording(also clears markup data)
/path to script/script.py --jobid %JOBID%
usage- export recording leaving original untouched
/path to script/script.py --jobid %JOBID% --export

Code: Select all

#!/usr/bin/env python
from MythTV import Job, Program, Recorded, System, MythDB, findfile, MythError, MythLog, datetime
import argparse
import subprocess
import os
import sys
import shutil
from glob import glob
import time
from datetime import timedelta
import logging
db=MythDB()
#I used the script here https://www.mythtv.org/wiki/Transcode_Mpeg2_to_H264
#as a starting point in creating this script
#usage - /path to script/transcode-export.py --jobid %JOBID%
# this will replace the original recording
#if used as /path to script/transcode-export.py --jobid %JOBID% --export
#original file will be untouched and new file with a Kodi compatible file name
#will be created in the export directory

#####video options#####
#####container format#####
#compatible options are 'mp4' or 'mkv'
Format = 'mkv'
#####Video codec selection#####
#h.264(libx264) tested|h.265(libx265) and VP-8/VP-9(libvpx,libvpx-vp9) crf available for testing
#encoder availablity dependent on ffmpeg/mythffmpeg version
Video_codec_HD = 'libx264'
Video_codec_SD = 'libx264'
#####H.264/H.265 preset#####
preset_HD = 'fast'
preset_SD = 'slow'
##### encoder crf#####
crf_SD = 18
crf_HD = 20
#####VP-8/VP-9 options#####
vpx_bitrate = 0 #use 0 for crf encoding
#for constrained encoding set desired value
#####H.264 options#####
streaming = True # enables fast start for mp4 streaming
hdhr = True #enables vsync passthrough for when HDHR prime repeats timestamps
hdvideo_min_bitrate = 0
hdvideo_max_bitrate = 5500
NUM_SECS_VIDEO_BUF=3
device_bufsize = NUM_SECS_VIDEO_BUF*hdvideo_max_bitrate
#####audio options#####
Encode_audio_HD = True # if set to false for passthrough of original audio
Encode_audio_SD = True
# Bitrate_per_channel sets audio bit-rate by the number of channels
# default value 64000 gives you 128k for 2 channel and 384k for 5.1
Bitrate_per_channel_HD = 64000
Bitrate_per_channel_SD = 64000
Audio_encoder_HD = 'libfdk_aac' # default libfdk_aac encoder
Audio_encoder_SD = 'libfdk_aac' #if using mythffmpeg or libfdk_aac not installed
# use 'aac' for ffmpeg internal aac encoder
#Should support most available codecs
keep_51 = False # true enables passthrough of ac3 5.1 or greater audio 
#^note-this overides all other audio options
#####Vorbis settings#####
Audio_quality = 5 #audio quality setting for vorbis
############################
# audio language selection
language = 'eng'
# encode all tracks matching language not just the first.
all_lang = False
############################
#####Directory to export recordings to#####
exportdir ='/var/lib/mythtv/recordings/'
#sub directorys for TVshows,Movies,NonseriesTV will be created within this directory
############################
logdir ='/var/log/mythtv/'
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',filename='%transcode.log'%(logdir),filemode='w',level=logging.DEBUG)
def run_cut(jobid=None,infile=None,outfile=None,chanid=None,starttime=None,export=None):
    logging.info('Started')
    ffmpeg = prog_check()[0]
    ffprobe = prog_check()[1]
    logging.debug('ffmpeg=%s ffprobe=%s',ffmpeg,ffprobe)
    if jobid:
        job = Job(jobid, db=db)
        chanid = job.chanid
        utcstarttime = job.starttime
        logging.debug('chanid=%s starttime=%s',chanid,starttime)
        rec = Recorded((chanid,utcstarttime), db=db)
        logging.debug('DB recording entry=%s',rec)
        sg = findfile('/'+rec.basename, rec.storagegroup, db=db)
        infile = os.path.join(sg.dirname, rec.basename)
        Infile = infile.split('/')[-1]
        tmpdir = sg.dirname +'crtmp/'
        if export:
            outfile = metadata_setup(rec)[1] + metadata_setup(rec)[2] 
            if os.path.isdir(metadata_setup(rec)[1]):
                logging.debug('Export Directory found')
                "print" 'Directory found'
            elif not os.path.isdir(metadata_setup(rec)[1]):
                os.makedirs(metadata_setup(rec)[1])
                logging.debug('Export Directory created')
                print 'Directory created'
        if not export:
            outfile ='%s.%s' % (infile.split('.')[0],Format)
            Outfile = outfile.split('/')[-1]
        logging.debug('infile=%s outfile=%s',infile,outfile)

    if chanid and starttime != None:
        chanid = chanid
        starttime = starttime
        logging.debug('chanid=%s starttime=%s',chanid,starttime)
        tzoffset = local_time_offset() / (60*60)
        utcstarttime = datetime.strptime(starttime,"%Y%m%d%H%M%S")
        utcstarttime = utcstarttime + timedelta(hours=tzoffset)
        rec = Recorded((chanid,utcstarttime), db=db)
        logging.debug('DB recording entry=%s',rec)
        sg = findfile('/'+rec.basename, rec.storagegroup, db=db)
        infile = os.path.join(sg.dirname, rec.basename)
        Infile = infile.split('/')[-1]
        tmpdir = sg.dirname +'crtmp/'
        if export:
            outfile = metadata_setup(rec)[1]+ metadata_setup(rec)[2] 
            if os.path.isdir(metadata_setup(rec)[1]):
                logging.debug('Export Directory found')
                print 'Directory found'
            elif not os.path.isdir(metadata_setup(rec)[1]):
                os.makedirs(metadata_setup(rec)[1])
                logging.debug('Export Directory created')
                print 'Directory created'
        if not export:
            outfile ='%s.%s' % (infile.split('.')[0],Format)
            Outfile = outfile.split('/')[-1]
        logging.debug('infile=%s outfile=%s',infile,outfile)
    elif infile and outfile != None:
        infile = infile
        Infile = infile.split('/')[-1]
        chanid = Infile.split('_')[0]
        starttime = Infile.split('_')[1].split('.')[0]
        logging.debug('chanid=%s starttime=%s',chanid,starttime)
        tzoffset = local_time_offset() / (60*60)
        utcstarttime = datetime.strptime(starttime, "%Y%m%d%H%M%S")
        utcstarttime = utcstarttime + timedelta(hours=tzoffset)
        rec = Recorded((chanid,utcstarttime), db=db)
        logging.debug('DB recording entry=%s',rec)
        tmpdir = '%scrtmp/' % infile.strip(Infile)      
        outfile = '%s.%s' % (outfile.split('.')[0],Format)
        Outfile = outfile.split('/')[-1]
        outdir = outfile.rstrip(Outfile)
        logging.debug('infile=%s outfile=%s',infile,outfile)
        
    tmp_chk(tmpdir)
    tmpfile = '%s%s.ts' % (tmpdir,Infile.split('.')[0])
    logging.debug('temp file=%s',tmpfile)

    if rec.cutlist == 1:
        if jobid:
            job.update({'status':job.RUNNING, 'comment':'Removing Cutlist'})
        logging.info('getting cutlist')
        cut_list =''.join(str(rec.markup.getcutlist())).replace('[','').replace(']','').replace('(','').replace(')','').replace(' ','')
        cutlist = cut_list
        if cutlist.startswith('0,'):
            cutlist = cutlist.replace("0,",'',1)
        if cutlist.endswith(',9999999'):
            cutlist = cutlist.replace(",9999999",'',-1)
        logging.debug('Myth cutlist:%s',cut_list)
        logging.debug('FFmpeg cutlist:%s',cutlist)
        logging.info('cutting started')
        cut =subprocess.Popen([ffmpeg,'-i',infile,'-c','copy','-map','0','-f','segment','-segment_list','%scut.ffcat'%(tmpdir),'-segment_frames',cutlist,'%scut%%03d.ts'%(tmpdir)],stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        output = cut.communicate()[0]
        if cut.wait() == 0:
            if jobid:
                job.update({'status':job.RUNNING, 'comment':'Cuting Finished'})
            logging.info('Cuting Finished')
        if cut.wait() != 0:
            if jobid:
                job.update({'status':job.ERRORED, 'comment':'FFMPEG ERROR: cutiing'})
            logging.error('FFMPEG ERROR: cutiing')
            logging.error('%s',output)
            sys.exit(1)

        if jobid:
            job.update({'status':job.RUNNING, 'comment':'Merging Cuts'})
        logging.info('Merging Cuts')
        j = []
        for root, dirs, files in os.walk(tmpdir):
            for files in files:
                if files.endswith('.ts') and files.startswith('cut'):
                    if os.path.isfile(os.path.join(root,files)):
                        j.append(os.path.join(root,files))
        if cut_list.startswith('0,'):
          ls = j[1::2]
        if not cut_list.startswith('0,'):
          ls = j[0::2]
        q =','.join(ls).replace(',','|')
        logging.debug('concat list:%s' % q)
        join =subprocess.Popen([ffmpeg,'-y','-i','concat:%s'%q,'-map','0','-c','copy','-f','mpegts',tmpfile],stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        output = join.communicate()[0]
        if join.wait() == 0:
            if jobid:
                job.update({'status':job.RUNNING, 'comment':'Merging Finished'})
            logging.info('Merging Finished') 
        if join.wait() != 0:
            if jobid:
                job.update({'status':job.ERRORED, 'comment':'FFMPEG ERROR: merging'})
            logging.error('FFMPEG ERROR: merging')
            logging.error('%s',output)
            sys.exit()
    if rec.cutlist == 0:
        if jobid:
            job.update({'status':job.RUNNING, 'comment':'Creating temporary file for transcoding.'})
        logging.info('No cutlist: copying input file to temp directory')
        shutil.copyfile('%s' % infile, '%s' % tmpfile)
    logging.info('extracting CC')
    if jobid:
        job.update({'status':job.RUNNING, 'comment':'Extracting Closded Captions.'})

    cc = subprocess.Popen(['mythccextractor','-i', tmpfile],stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
    output = cc.communicate()[0]
    if cc.wait() == 0:
        if jobid:
            job.update({'status':job.RUNNING, 'comment':'Subtitle file extracted'})
        logging.info('Subtitle file extracted from:%s',tmpfile)
    if cc.wait() != 0:
        if jobid:
            job.update({'status':job.ERRORED, 'comment':'Mythccextractor ERROR: extracting CC'})
        logging.error('Mythccextractor ERROR: extracting CC from:%s',tmpfile)
        logging.error('%s',output)
        sys.exit(1)

    isHD = HD_check(info_check(ffprobe, infile))
    logging.debug('isHD=%s',isHD)
    v_param = video_setup(isHD)
    logging.debug('v_param=%s',v_param)
    a_param = audio_setup(info_check(ffprobe, infile), isHD, infile)
    logging.debug('a_param=%s',a_param)
    m_param = metadata_setup(rec)[0]
    logging.debug('m_param=%s',m_param)

    if sub_check(tmpdir,tmpfile,Format) != None:
        s_param = sub_check(tmpdir,tmpfile,Format)
    else:
        s_param = None
    if s_param != None:
        logging.debug('s_param=%s',s_param)
        enc_param = '%s %s %s %s'.strip() % (s_param[0],v_param,a_param,s_param[1])
    if s_param == None:
        enc_param = '%s %s'.strip() % (v_param,a_param)
        logging.debug('(None)s_param=%s',s_param)
    encparamlist = enc_param.split(' ')
    logging.debug('encparam=%s',encparamlist)
    command = [ffmpeg,'-y','-i',tmpfile] + encparamlist + m_param + [outfile]
    logging.debug('encoding command=%s',command)
    logging.info('Encoding Started')
    if jobid:
        job.update({'status':job.RUNNING, 'comment':'Encoding Started'})
    try:
        enc = subprocess.Popen(command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        output = enc.communicate()[0]
        if enc.wait() == 0:
            if jobid:
                job.update({'status':job.RUNNING, 'comment':'Encoding Finished'})
            logging.info('encoding finished')
        if enc.wait() != 0:
            if jobid:
                job.update({'status':job.ERRORED, 'comment':'FFMPEG ERROR: encoding'})
            logging.error('FFMPEG ERROR: encoding')
            logging.error('%s',output)
            sys.exit(1)
    except Exception as e:
        logging.error('%s',e)
        sys.exit(1)

    logging.debug('clear markup?')
    if not export:
        clear_markup(rec,infile,outfile)

    rem_tmp(tmpdir)

def metadata_setup(rec):
    prog = Program.fromRecorded(rec)
    category = rec.category
    Title = rec.title
    Subtitle = rec.subtitle
    Description = rec.description
    Season = rec.season
    Episode = rec.episode
    Year = prog.year
    Date = rec.starttime.strftime('%Y-%m-%d-%I%p')
    
    if category != 'Movie' or category != 'Series':
        title = "-metadata,Show=%s" % Title
        if Subtitle != None or '':
            subtitle = "-metadata,title=%s" % Subtitle
        else:
            subtitle = ''
        if Description != None or '':
            description = "-metadata,description=%s" % Description
        else:
            description = ''
        if Season != None or '':
            season = "-metadata,seasonnumber=%02d" % Season
        else:
            season = ''
        if Episode != None or '':
            episode = "-metadata,episodenumber=%02d" % Episode
        else:
            episode = ''
        dirname = '%s/NonseriesTV/%s' % (exportdir,Title)
        filename = '%s %s.%s' % (Title,Date,Format)
    if category == 'Movie':
        title = "-metadata,title=%s(%s)" % (Title,Year)
        subtitle = ""
        description = "-metadata,description=%s" % Description
        season = ""
        episode = ""
        dirname = '%sMovies/%s(%s)/' % (exportdir,Title,Year)
        filename = '%s(%s).%s' % (Title,Year,Format)
    if category == 'Series':
        title = "-metadata,Show=%s" % Title
        subtitle = "-metadata,title=%s" % Subtitle
        description = "-metadata,description=%s" % Description
        season = "-metadata,seasonnumber=%02d" % Season
        episode = "-metadata,episodenumber=%02d" % Episode
        dirname = '%sTVshows/%s/season %02d/' % (exportdir,Title,Season)
        filename = '%s S%02dE%02d (%s).%s' % (Title,Season,Episode,Subtitle,Format)
    metadata_param = "{},{},{},{},{}".format(title,subtitle,description,season,episode).rstrip("")
    m_param =metadata_param.split(',')
    return m_param,dirname,filename

def clear_markup(rec,infile,outfile):
    logging.debug('rec=%s infile=%s outfile=%s',rec,infile,outfile)
    chanid = rec.chanid
    utcstarttime = rec.starttime
    starttime = str(utcstarttime.utcisoformat().replace(u':', '').replace(u' ', '').replace(u'T', '').replace('-', ''))
    logging.debug('chanid=%s starttime=%s',chanid,starttime)
    logging.info('start clearing markup')
    try:
        rcl = subprocess.Popen(['mythutil','--chanid',str(chanid),'--starttime',str(starttime),'--clearcutlist'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        output1 = rcl.communicate()
        if rcl.wait() == 0:
            logging.info('Cutlist removed for:%s_%s',chanid,starttime)
            logging.debug('%s',output1)
        if rcl.wait() != 0:
            logging.error('MYTHUTIL ERROR: clearing cutlist for:%s_%s',chanid,starttime)
            logging.error('%s',output1)
    except Exception as e:
        logging.error('Mythutil exception clearing cutlist%s',e)
    try:
        rsl = subprocess.Popen(['mythutil','--chanid',str(chanid),'--starttime',str(starttime),'--clearskiplist'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        output2 = rsl.communicate()[0]
        if rsl.wait() == 0:
            logging.info('Skiplist removed for:%s_%s',chanid,starttime)
            logging.debug('%s',output2)
        if rsl.wait() != 0:
            logging.error('MYTHUTIL ERROR: clearing skiplist for:%s_%s',chanid,starttime)
            logging.error('%s',output2)
    except Exception as e:
        logging.error('Mythutil exception clearing skiplist:%s',e)

    for index,mark in reversed(list(enumerate(rec.markup))):
        if mark.type in (rec.markup.MARK_COMM_START, rec.markup.MARK_COMM_END):
            del rec.markup[index]
    rec.bookmark = 0
    rec.cutlist = 0
    rec.commflagged = 0
    rec.markup.commit()
    rec.basename = os.path.basename(outfile)
    rec.filesize = os.path.getsize(outfile)
    rec.transcoded = 1
    rec.seek.clean()
    rec.update()
    os.remove(infile)
    for filename in glob('%s*.png' % infile):
        os.remove(filename)

def tmp_chk(tmpdir):
        try:
            if os.path.isdir(tmpdir):
                logging.info('temp Folder found:')
                if os.listdir(tmpdir) != 0:
                    logging.warning('Temp folder not empty!:Removing Files:')
                    shutil.rmtree(tmpdir)
                    os.makedirs(tmpdir)
            if not os.path.isdir(tmpdir):
                logging.info('no temp folder found:')
                os.makedirs(tmpdir)
                logging.info('Temp folder created:')
        except Exception as e:
            logging.error('%s',e)
def rem_tmp(tmpdir):
            try:
                if os.path.isdir(tmpdir):
                    logging.info('temp Folder found')
                    shutil.rmtree(tmpdir)
                    logging.info('Temp Folder Removed')
                if not os.path.isdir(tmpdir):
                    logging.info('no temp folder found')
            except Exception as e:
                logging.error('%s',e)
def local_time_offset(t=None):
    if t is None:
        t = time.time()

    if time.localtime(t).tm_isdst and time.daylight:
        return -time.altzone
    else:
        return -time.timezone
def prog_check():
    try:
        if os.path.isfile('/usr/bin/ffmpeg'):
            ffmpeg = '/usr/bin/ffmpeg'
        elif not os.path.isfile('/usr/bin/ffmpeg') and os.path.isfile('/usr/bin/mythffmpeg'):
            ffmpeg = '/usr/bin/mythffmpeg'
    except Exception as e:
        logging.error('%s',e)
    try:
        if os.path.isfile('/home/myth/bin/ffprobe'):
            ffprobe ='/usr/bin/ffprobe'
        elif not os.path.isfile('/usr/ffprobe') and os.path.isfile('/usr/bin/mythffmpeg'):
            ffprobe = 'usr/bin/mythffmpeg'
    except Exception as e1:
        logging.error('%s',e1)
    logging.debug('ffmpeg=%s ffprobe=%s',ffmpeg,ffprobe)
    return ffmpeg,ffprobe
def CC_to_ST(outfile):
    cc = subprocess.Popen(['mythccextractor','-i', outfile],stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
    output = cc.communicate()[0]
    if debug:
        print output
    if cc.wait() == 0:
        print 'Subtitle file extracted from:\n%s' % outfile
    if cc.wait() != 0:
        print 'FFMPEG ERROR: extracting CC from:\n%s' % outfile

def info_check(ffprobe, infile):
    ic = subprocess.Popen([ffprobe, '-v', '-8', '-show_entries',\
                           'stream=index,codec_name,channels,width,\
height,r_frame_rate:stream_tags=language', '-of',\
                           'csv=nk=1:p=0', '%s' % infile],\
                          stdout = subprocess.PIPE, \
                          stderr = subprocess.STDOUT)
    info = ic.communicate()[0].split('\n')
    video_info = info[0].split(',')
    width = int(video_info[2])
    height = int(video_info[3])
    rfps = video_info[4].split('/')
    fps = round(float(float(rfps[0]) / float(rfps[1])),2)
    for line in info:
        if line.startswith('1') and \
           line.endswith(('eng','fre','ger','ita','spa')):
            track1 = line
    for line2 in info:
        if line2.startswith('2') and \
           line2.endswith(('eng','fre','ger','ita','spa')):
            track2 = line2
        if not line2.startswith('2') and \
           line2.endswith(('eng','fre','ger','ita','spa')):
            track2 = None
    return width, height, fps, track1, track2

def audio_setup(info_check, isHD, infile):
    track1 = info_check[3].split(',')
    if info_check[4] != None:
        track2 = info_check[4].split(',')
    else:
        track2 = None

    if language != None:
        if track1[4] == '%s' % language:
            TS = '1'
        elif track1[4] != '%s' and track2[4] == '%s' % language:
            TS = '2'
        if track2 != None and all_lang == True and track1[4] and track2[4] == '%s' % language:
            STR = '-map 0:2 '
        else:
            STR =''
    if language == None:
        TS = '1'
        STR = ''
    if TS == '1':
        TR = track1
    elif TS == '2':
        TR = track2
    if keep_51 == True and TR[1] == 'ac3' and TR[2] >= '6':
        AENC = 'copy'
    else:
        if isHD == True:
            if Encode_audio_HD == True:
                AENC = Audio_encoder_HD
            elif Encode_audio_HD == False:
                AENC = 'copy'
        elif isHD == False:
            if Encode_audio_SD == True:
                AENC = Audio_encoder_SD
            elif Encode_audio_SD == False:
                AENC = 'copy'
    if AENC == 'copy':
        ABR = ''
        LANG = "{}{}".format('-metadata:s:a:0 language=', '%s' % TR[4])
    if AENC != 'copy':
        LANG = "{}{}".format(' -metadata:s:a:0 language=', '%s' % TR[4])
        if isHD == True:
            if Encode_audio_HD == True:
                if Audio_encoder_HD == 'libvorbis':
                    ABR = "{} {}".format('-q:a', Audio_quality)
                else:
                    ABR ="{} {}".format('-b:a', int(int(Bitrate_per_channel_HD)* int(TR[2])))
        if isHD == False:
            if Encode_audio_SD == True:
                if Audio_encoder_HD == 'libvorbis':
                   ABR = "{} {}".format('-q:a', Audio_quality)
                else:
                    ABR ="{} {}".format('-b:a', \
                int(int(Bitrate_per_channel_SD)* int(TR[2])))
            else:
                ABR = ''
    a_param ="{}".format\
    ("-map 0:" '%s'' %s''-c:a' ' %s' ' %s' '%s' % (TS,STR,AENC,ABR,LANG))
    abitrate_param = a_param.strip()
    return abitrate_param

def HD_check(info_check):
        width = info_check[0]
        height = info_check[1]
        if width >= 1280 and height >= 720:
            return True
        else:
            return False

def video_setup(isHD):
    if isHD == True:
        VENC = Video_codec_HD
    if isHD == False:
        VENC = Video_codec_SD
    if isHD and Video_codec_HD == 'libx264':
        DIF = ' -filter:v yadif=0:-1:1'
        if streaming == True:
            FS = ' -movflags faststart'
        else:
            FS = ''
        if hdhr == True:
            VSP = ' -vsync passthrough'
        else:
            VSP = ''
        if preset_HD != None:
            PRES = " {} {}".format("-preset:v", preset_HD)
        if preset_HD == None:
            PRES = ''
        CRF = " -crf:v %s" % crf_HD
        if hdvideo_min_bitrate > 0:
            MINR = " -minrate %sk" % hdvideo_min_bitrate
        if hdvideo_min_bitrate == 0:
            MINR = ""
        if hdvideo_max_bitrate > 0:
            MAXR = " -maxrate %sk" % hdvideo_max_bitrate
        if hdvideo_max_bitrate == 0:
            MAXR = ""
        if hdvideo_max_bitrate > 0 or hdvideo_min_bitrate > 0:
                BUFS = " -bufsize %sk" % device_bufsize
    if not isHD and Video_codec_SD == 'libx264':
        DIF = ' -filter:v yadif=0:-1:1'
        if streaming == True:
            FS = ' -movflags faststart'
        else:
            FS = ''
        if hdhr == True:
            VSP = ' -vsync passthrough'
        if preset_SD != None:
            PRES = " {} {}".format("-preset:v", preset_SD)
        if preset_HD == None:
            PRES = ''
        CRF = " -crf:v %s" % crf_SD
        MINR = ''
        MAXR = ''
        BUFS = ''
    if isHD and Video_codec_HD == 'libx265':
        DIF = ''
        FS = ''
        VSP = ''
        if preset_HD != None:
            PRES = " {} {}".format('-preset:v', preset_HD)
        if preset_HD == None:
            PRES = ''
        CRF = " -crf:v %s" % crf_HD
        MINR = ''
        MAXR = ''
        BUFS = ''
    if not isHD and Video_codec_SD == 'libx265':
        DIF = ''
        FS = ''
        VSP = ''
        if preset_HD != None:
            PRES = " {} {} {}".format('-preset:v', preset_SD, '-x256-params')
        if preset_HD == None:
            PRES = ''
        CRF = " -crf:v %s" % crf_SD
        MINR = ''
        MAXR = ''
        BUFS = ''
    if isHD and Video_codec_HD == 'libvpx-vp9':
        DIF = ''
        FS = ''
        VSP = ''
        PRES = ''
        CRF = " -crf:v %s" % crf_HD
        MINR = ''
        MAXR = ' -b:v %s' % vpx_bitrate
        BUFS = ''
    if not isHD and Video_codec_HD == 'libvpx-vp9':
        DIF = ''
        FS = ''
        VSP = ''
        PRES = ''
        CRF = " -crf:v %s" % crf_SD
        MINR = ''
        MAXR = ' -b:v %s' % vpx_bitrate
        BUFS = ''
    if isHD and Video_codec_HD == 'libvpx':
        DIF = ''
        FS = ''
        VSP = ''
        PRES = ''
        CRF = " -crf:v %s" % crf_HD
        MINR = ''
        MAXR = ' -b:v %s' % vpx_bitrate
        BUFS = ''
    if not isHD and Video_codec_HD == 'libvpx':
        DIF = ''
        FS = ''
        VSP = ''
        PRES = ''
        CRF = " -crf:v %s" % crf_SD
        MINR = ''
        MAXR = ' -b:v %s' % vpx_bitrate
        BUFS = ''
    v_param = "{}".format('-map 0:0' '%s'\
    '%s' '%s' ' -c:v ' '%s' '%s' '%s' '%s' '%s' '%s'\
                            % (DIF,FS,VSP,VENC,PRES,CRF,MINR,MAXR,BUFS))
    vbitrate_param = v_param.strip()
    return vbitrate_param

def sub_check(tmpdir,tmpfile,Format):
    Tmpfile = tmpfile.split('/')[-1].split('.')[0]
    s608 = None
    s708 = None
    for root, dirs, files in os.walk(tmpdir):
        for file in files:
            if file.endswith('.srt') and file.startswith(Tmpfile.rsplit('.')[0]) and '608-cc1' in file:
                s608 = (os.path.join(root,file))
    for root, dirs, files in os.walk(tmpdir):
        for file in files:
            if file.endswith('.srt') and file.startswith(Tmpfile.rsplit('.')[0]) and '708-service-01' in file:
                s708 = (os.path.join(root,file))
    if s608 or s708 != None:
        if s608 != None and s708 == None:
            sub = '-i %s' % s608
            subl = '-metadata:s:s:0 language=%s'% s608.split('.')[-2]
        elif s608 == None and s708 != None:
            sub ='-i %s' % s708
            subl = '-metadata:s:s:0 language=%s' % s708.split('.')[-2]
        elif s608 and s708 != None:
            sub ='-i %s' % s708
            subl = '-metadata:s:s:0 language=%s' % s708.split('.')[-2]
        elif s608 and s708 == None:
            sub = None
            subl = None
        if Format == 'mkv':
            subc = '-c:s srt'
        elif Format == 'mp4':
            subc = '-c:s mov_text'
        else:
            subc = ''
        sub_param = '-map 1:0 %s %s' % (subc,subl)
        return sub,sub_param
    else:
        return None
def main():
    parser = argparse.ArgumentParser(description='MythTV Commercial removal transcode and export')
    parser.add_argument('-i',action='store',type=str,dest='infile',help='Input file to be processed Must be formated chanid_starttime.ext for comercial removal')
    parser.add_argument('-o',action='store',type=str,dest='outfile',help='Output file to be created')
    parser.add_argument('--chanid',action='store',type=str,dest='chanid',help='Channel-Id of Recording')
    parser.add_argument('--starttime',action='store',type=str,dest='starttime',help='Starttime of recording in utc format')
    parser.add_argument('--jobid',action='store',type=int,dest='jobid',help='JOBID')
    parser.add_argument('--export',action='store_true',help='exports file to export dir in Kodi compatible format')
    args = parser.parse_args()
    if args.jobid:
        run_cut(jobid=args.jobid,export=args.export)
        sys.exit(0)
    if args.chanid and args.starttime:
        run_cut(chanid=args.chanid,starttime=args.starttime,export=args.export)
        sys.exit(0)
    if args.infile and args.outfile:
        run_cut(infile=args.infile,outfile=args.outfile)
        sys.exit(0)
    else:
        print 'jobid or chanid and starttime required'
main()

Post Reply