[mythtv-users] Share your transcode settings!

Jeremy Jones jeremy.dwain.jones at gmail.com
Thu Jan 12 14:18:19 UTC 2012


On Wed, Jan 11, 2012 at 11:13 AM, Jeremy Jones <jeremy.dwain.jones at gmail.com
> wrote:

>
>
> On Wed, Jan 11, 2012 at 10:26 AM, Josh Rosenberg <mythtv at desh.info> wrote:
>
>> All,
>>
>> I'm still struggling a lot with setting up transcoding.  But rather
>> than ask for specific help, I'm going to try a different approach.
>>
>> Those of you who do any sort of lossy or format-converting transcoding
>> beyond just stripping commercials, share how you do it!  Built-in
>> transcoding, a user job, or what?
>
>
> I am transcoding to mpeg-2 standard definition (480p) from High Definition
> content.  This cannot be done with built-in transcoders, because anything
> that changes the resolution makes the container a nuv (nupple Video file).
>  So I asked a similar question.  you can find the thread by googling,
> "mythtv Replacing mythtranscode command with a custom script".   But to
> make a long thread short, I ended up using the "transcode wrapper stub"
> from the wiki http://www.mythtv.org/wiki/Transcode_wrapper_stub, which
> will take care of replacing the original file and everything for you after
> transcoding.  The stub just needs your transcode command added to it.  I'll
> post mine tonight as a follow up to this thread, but until then there is at
> least one example called, " Low Quality Transcode" on the wiki
> http://www.mythtv.org/wiki/Low_Quality_Transcode.
>
> If you use a script someone posted
>> online, have you modified it?  If you use a standard utility like
>> ffmpeg,
>
>
> I am using ffmpeg from within the stub.
>
>
>> or a script with multiple modes, what options do you call it
>> with?
>
>
> No multiple modes in mine.  I call mine by replacing the built-in
> transcoder, but it can be run as a user job.  I chose to replace it, so
> that I could have the transcodeing run before commercial flagging.
>
>
> Also, how long does the conversion take and how well does it
>> work for you (that is, how much space does it save and how is the
>> quality impacted)?
>>
>
> Saves a lot of space, but yes quality is impacted, since I am actually
> changing (for compatibility with a network player) to Standard Definition
> instead of High Definition.  Regardless of that, I would still recommend
> using Raymonds wrapper for whatever your setting are.  Other posters may
> have more fitting information on ffmpeg settings. (or mencoder, or
> handbrake)  It just need to be able to be executed from a cli for the stub
> to use it.
>
>
>> Bonus points for explaining why you chose what you chose, or what
>> alternatives you've discarded along the way.
>>
>
> I chose to use ffmpeg because I already had it and it seems to be very
> popular.  I just google for settings that other users had and tried
> different variations until I got output that worked with my network player.
>  Once I had that I wrote a script and called it as a user job.  I had
> problems though swapping out the files.  The end result had the mythtv file
> and the transcoded one.  I had something that was working, but it was not
> consistent and actually returned errors in mythtv.  Then I discovered the
> wrapper stub, and it made everything easier.  I just abandoned my script
> and put my ffmpeg command into that new script and ran it as the user job.
>
> Then I discovered that the commercial skip wasn't working and so I
> asked questions here. Turns out the commercial flags are frame specific and
> if your transcoding changes frames, then the flags are no good.  So I now
> had to run a second user job to flag the commercials.  In getting help on
> setting that up someone pointed me to actually changing the mythtv
> transcode  command.  I posted asking fo help doing that.  See the thread
> starting here:
> http://www.gossamer-threads.com/lists/mythtv/users/490927?do=post_view_threaded#490927
>
>>
>> Google searching for transcode help seems to mostly reveal people who
>> are struggling, and I'd like to hear some examples from people who are
>> succeeding!  Regardless of whether your use case exactly matches mine
>> or not.
>>
>> Thanks!
>>
>> Josh
>>
>> Like I said, I will post my entire script tonight when I have access to
> my computer.
>
> Jeremy
>
>
>

As promised I copied the script below and attached it, but I am not sure if
attaching files works or is acceptable here.  I run this for all recordings
that I transcode, so I just replaced 'joQueueTranscodeCommand' with
'/home/username/DVDtranscode.py %JOBID%'  It can be called just as easily
as a user job though.

The script is based on the the transcode wrapper stub on the wiki.  I would
recommend starting with the one on the wiki and adding your own command for
"output".  Raymond has plenty of good comments in there for what you need
to change and/or add. I added some lines to mine that I thought would help
me troubleshoot some things, but I don't know if they really do anything or
not.  That is why I don't recommend starting with mine.  Just use it as an
example.  As you can see I am using ffmpeg to do the transcoding and the
command I use is there in the script.  FFMPEG is pretty well documented and
pretty customize-able on what you want to do, but post back for help if you
need it.  I'll share the little that I have learned about it, and I'm sure
there are others who can be of *much* better help here too.

Jeremy



Finlename: DVDtranscode.py

code begins below the line:
-------------------------------------------------
#!/usr/bin/env python

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

from optparse import OptionParser
import sys
import os

################################
#### adjust these as needed ####
transcoder = '/usr/bin/ffmpeg'
flush_commskip = False
build_seektable = False
################################

def runjob(jobid=None, chanid=None, starttime=None):
    db = MythDB()
    job = Job(jobid, db=db)
    chanid = job.chanid
    starttime = job.starttime
    rec = Recorded((chanid, starttime), db=db)
    if jobid:
        job.update({'status':4, 'comment':'Running as %jobid'})

    sg = findfile(rec.basename, rec.storagegroup, db=db)
    if sg is None:
        if jobid:
            job.update({'status':4, 'comment':'Local access to recording
not found.'})
        print 'Local access to recording not found.'
        sys.exit(1)

    infile = os.path.join(sg.dirname, rec.basename)
    outfile = '%s.mpeg' % infile.rsplit('.',1)[0]
    #### list of segments to be cut
    # rec.markup.gencutlist()
    #### list of segments to keep
    # rec.markup.genuncutlist()
    if jobid:
        job.update({'status':4, 'comment':'starting ffmpeg'})

    task = System(path=transcoder, db=db)
    try:
##############################################
#### probably need to adjust this one too ####
        output = task('-y -i "%s" -target ntsc-dvd -async 1 "%s" 2>
/dev/null ' % (infile, outfile) )
##############################################
        if jobid:
            job.update({'status':4, 'comment':'ffmpeg complete'})
    except MythError, e:
        if jobid:
            job.update({'status':8, 'comment':'ffmpeg threw an error'})
        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 jobid:
        job.update({'status':4, 'comment':'Removed old File'})

    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_END):
                del rec.markup[index]
        rec.bookmark = 0
        rec.cutlist = 0
        rec.markup.commit()
        if jobid:
            job.update({'status':4, 'comment':'Comm_Flushed'})

    if build_seektable:
        task = System(path='mythcommflag')
        task.command('--chanid %s' % chanid,
                     '--starttime %s' % starttime,
                     '--rebuild')
        if jobid:
            job.update({'status':4, 'comment':'rebuilt seektable'})

    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='starttime',
            help='Use starttime for manual operation')
    parser.add_option('-v', '--verbose', action='store', type='string',
dest='verbose',
            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()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.mythtv.org/pipermail/mythtv-users/attachments/20120112/0a763f42/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: DVDtranscode.py
Type: application/octet-stream
Size: 3711 bytes
Desc: not available
Url : http://www.mythtv.org/pipermail/mythtv-users/attachments/20120112/0a763f42/attachment.obj 


More information about the mythtv-users mailing list