[mythtv-users] transcode_stub.py and HandBrakeCLI

Mark Boyum mark at boyum.us
Sat Oct 5 18:47:47 UTC 2013


Hello MythTV people,

I've attempted to hack the transcode_stub.py from the wiki, not
knowing anything about python, so that it will create .mkv's using
HandBrakeCLI.  It fires off from the job queue as expected.  Top shows
HandBrakeCLI using a good amount of CPU time and then it just goes
idle after about 30 minutes.

So it seems that Myth launches transcode_stub.py as a user job.
Transcode_stub.py launches HandBrakeCLI which appears to do work.  I
can see the .mkv growing in size.

When the .mkv stops growing, HandBrakeCLI shows up in ps -A as does
python.  Both the original .mpg and the .mkv exist in the directory at
this point and the only way to move on is to kill the HandBrakeCLI
process.  Then MythTV reports the user job as failed.

If I just run the HandBrakeCLI command it works as expected.

How do I determine why HandBrakeCLI isn't exiting when the transcode
appears complete?

Here is the modified transcode_stub.py:
#!/usr/bin/env python

from MythTV import Job, Recorded, System, MythDB, findfile, MythError, MythLog

from optparse import OptionParser
import sys
import os

################################
#### adjust these as needed ####
transcoder = 'HandBrakeCLI -5 --preset=Normal'
flush_commskip = False
build_seektable = False
################################

def runjob(jobid=None, chanid=None, starttime=None):
    db = MythDB()
    if jobid:
        job = Job(jobid, db=db)
        chanid = job.chanid
        starttime = job.starttime
    rec = Recorded((chanid, starttime), db=db)

    sg = findfile(rec.basename, rec.storagegroup, db=db)
    if sg is None:
        print 'Local access to recording not found.'
        sys.exit(1)

    infile = os.path.join(sg.dirname, rec.basename)
    outfile = '%s.mkv' % infile.rsplit('.',1)[0]
    #### list of segments to be cut
    # rec.markup.gencutlist()
    #### list of segments to keep
    # rec.markup.genuncutlist()

    task = System(path=transcoder, db=db)
    try:
##############################################
#### probably need to adjust this one too ####
#       os.nice(5)
        output = task('-i "%s"' % infile,
                      '-o "%s"' % outfile)
##############################################
    except MythError, e:
        print 'Command failed with output:\n%s' % e.stderr
        sys.exit(e.returncode)

    rec.basename = os.path.basename(outfile)
    os.remove(infile)
    rec.filesize = os.path.getsize(outfile)
    rec.transcoded = 1
    rec.seek.clean()

    if flush_commskip:
        for index,mark in reversed(list(enumerate(rec.markup))):
            if mark.type in (rec.markup.MARK_COMM_START, rec.markup.MARK_COMM_E$
                del rec.markup[index]
        rec.bookmark = 0
        rec.cutlist = 0
        rec.markup.commit()

    if build_seektable:
        task = System(path='mythcommflag')
        task.command('--chanid %s' % chanid,
                     '--starttime %s' % starttime,
                     '--rebuild')

    rec.update()

    if jobid:
        job.update({'status':272, 'comment':'Transcode Completed'})

def main():
    parser = OptionParser(usage="usage: %prog [options] [jobid]")

    parser.add_option('--chanid', action='store', type='int', dest='chanid',
            help='Use chanid for manual operation')
    parser.add_option('--starttime', action='store', type='int', dest='starttim$
            help='Use starttime for manual operation')
    parser.add_option('-v', '--verbose', action='store', type='string', dest='v$
            help='Verbosity level')

    opts, args = parser.parse_args()

    if opts.verbose:
        if opts.verbose == 'help':
            print MythLog.helptext
            sys.exit(0)
        MythLog._setlevel(opts.verbose)

    if len(args) == 1:
        runjob(jobid=args[0])
    elif opts.chanid and opts.starttime:
        runjob(chanid=opts.chanid, starttime=opts.starttime)
    else:
        print 'Script must be provided jobid, or chanid and starttime.'
        sys.exit(1)

if __name__ == '__main__':
    main()


More information about the mythtv-users mailing list