mythtranscode --audiotrack ???

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

Moderator: Forum Moderators

Post Reply
bpmod
Junior
Posts: 27
Joined: Fri Mar 25, 2016 3:42 pm
Canada

mythtranscode --audiotrack ???

Post by bpmod » Sun Jan 15, 2017 12:44 am

I have been searching for over a week and I haven't yet found the answer as to what replaces the question marks in the above command.

I need to specify a particular audio stream when I am transcoding because mythtranscode does irregular things with audio streams. Sometimes it switches them around, sometimes it chooses one or another. And always, (sort of) by design, it strips the metadata from all of them. The next step in my script needs to know what audio stream to use, and the only thing I can figure out to tell it is to take the first one. If mythtranscode moves the 'correct' stream to the second position, the rest of the script fails.

I can quite easily rewrite my script to have mythtranscode take out any audio streams I do not want or need, but this adds time and cpu cycles to the operation. I am trying to do a large number of recordings, hence the script. EDIT: I thought I had found the instructions for this in my search for answers, but I can no longer find whatever it was that made me think that was an option.

As far as running the command, I have tried specifying the audio stream I want but everything I have tried, letters, numbers, alphanumeric combinations with or without other characters, has failed. Of course, one of the other frustrating things is it never tells me there is an error in my syntax; it just ignores the option entirely.

Incidentally, I am running fixes/0.28 under Mythbuntu 16.04.

Please help!

Brian
Last edited by bpmod on Mon Jan 16, 2017 3:10 pm, edited 1 time in total.

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

Re: mythtranscode --audiotrack ???

Post by daraden » Sun Jan 15, 2017 9:56 am

are you using the .mpg extension for the output? converting the .ts(mpeg transport stream) to .mpg( mpeg program stream) gave me all of the issues you are listing on .27(have not used it in .28).

The issue is that mpeg prorgam streams only natively support mpeg audio streams and metadata is not supported.

Take a look at the original files that are causing issues with ffprobe(mythffprobe if you don't have ffmpeg installed). Are the audio channels and bit rate the same? I have channels that both tracks are stereo 192kbps and it would always flip the track order. Ended up adding a patch to my old script that would reverse the order if the recording was on those channels.

you could try using the .ts extension and if you need .mpg renaming the file afterwards should work.
or be difficult like me and write a replacement to do what you need.

bpmod
Junior
Posts: 27
Joined: Fri Mar 25, 2016 3:42 pm
Canada

Re: mythtranscode --audiotrack ???

Post by bpmod » Mon Jan 16, 2017 3:08 pm

daraden wrote:are you using the .mpg extension for the output? converting the .ts(mpeg transport stream) to .mpg( mpeg program stream) gave me all of the issues you are listing on .27(have not used it in .28).
I had been, mostly because I didn't realize there was an option.
daraden wrote:The issue is that mpeg prorgam streams only natively support mpeg audio streams and metadata is not supported.
That is the issue with the metadata disappearing, but that has nothing to do (as far as I can tell) with the streams being swapped. I don't need the metadata because I can simply put it back into whatever container I create. What I do need is the audio stream(s) to be in the correct place(s).
daraden wrote:Take a look at the original files that are causing issues with ffprobe(mythffprobe if you don't have ffmpeg installed). Are the audio channels and bit rate the same? I have channels that both tracks are stereo 192kbps and it would always flip the track order. Ended up adding a patch to my old script that would reverse the order if the recording was on those channels.
No. The first audio file is 5.1 ac3 English; the second is 2.0 ac3 Middle English (that's the first time I've ever seen that language in the metadata). Some of them get switched by mythtranscode; some don't. If I could get mythtranscode to select one or the other (in my case it has, so far, always been the first) and pass along only one stream, it'd work great.
daraden wrote:you could try using the .ts extension and if you need .mpg renaming the file afterwards should work.
or be difficult like me and write a replacement to do what you need.
I was pleasantly surprised as to how easy that made things. The audio streams stay in their correct positions and nothing gets downmixed. (Although I have not had any trouble with the latter, I have read many posts online that show that has been an(other) issue with mythtranscode.)

BUT. The resulting .ts file does not seem to work. It throws a whole bunch of new errors.

I am still looking for somebody (a developer, hopefully) who knows the syntax to use for that command option.

Brian

User avatar
bill6502
Developer
Posts: 1374
Joined: Fri Feb 07, 2014 5:28 pm
United States of America

Re: mythtranscode --audiotrack ???

Post by bill6502 » Mon Jan 16, 2017 4:30 pm

I don't use let alone develop mythtranscode, however, the answer to
the syntax question can be found with:

Code: Select all

mythtranscode --help audiotrack
That help option is available with most mythSomeProgramName commands.
The answer to the above is int, as you already tried.

bpmod
Junior
Posts: 27
Joined: Fri Mar 25, 2016 3:42 pm
Canada

Re: mythtranscode --audiotrack ???

Post by bpmod » Mon Jan 16, 2017 5:46 pm

Thanks Bill.

Here is what happens when I use an integer: (three tries; three different integers)

Command:

Code: Select all

mythtranscode --chanid 1091 --starttime 20161217175900 --audiotrack 0 --honorcutlist -m -o xxxa.mpg
Output:

Code: Select all

2017-01-16 12:07:54.522865 C  mythtranscode version: fixes/0.28 [v0.28-100-g2d6466f] www.mythtv.org
2017-01-16 12:07:54.522887 C  Qt version: compile: 5.5.1, runtime: 5.5.1
2017-01-16 12:07:54.522892 N  Enabled verbose msgs:  general
2017-01-16 12:07:54.522904 N  Setting Log Level to LOG_INFO
2017-01-16 12:07:54.533504 I  Added logging to the console
2017-01-16 12:07:54.533862 I  Setup Interrupt handler
2017-01-16 12:07:54.533871 I  Setup Terminated handler
2017-01-16 12:07:54.533878 I  Setup Segmentation fault handler
2017-01-16 12:07:54.533884 I  Setup Aborted handler
2017-01-16 12:07:54.533891 I  Setup Bus error handler
2017-01-16 12:07:54.533896 I  Setup Floating point exception handler
2017-01-16 12:07:54.533903 I  Setup Illegal instruction handler
2017-01-16 12:07:54.533911 I  Setup Real-time signal 0 handler
2017-01-16 12:07:54.533919 I  Setup Hangup handler
2017-01-16 12:07:54.534005 N  Using runtime prefix = /usr
2017-01-16 12:07:54.534009 N  Using configuration directory = /home/brian/.mythtv
2017-01-16 12:07:54.534066 I  Assumed character encoding: en_CA.UTF-8
2017-01-16 12:07:54.534326 N  Empty LocalHostName.
2017-01-16 12:07:54.534331 I  Using localhost value of JACK
2017-01-16 12:07:54.583274 N  Setting QT default locale to en_CA
2017-01-16 12:07:54.583289 I  Current locale en_CA
2017-01-16 12:07:54.583367 N  Reading locale defaults from /usr/share/mythtv//locales/en_ca.xml
2017-01-16 12:07:54.594632 I  Loading en_ca translation for module mythfrontend
2017-01-16 12:07:54.598043 N  Transcoding from /var/lib/mythtv/recordings/1091_20161217175900.ts to xxxa.mpg
2017-01-16 12:07:54.598057 I  Honoring the cutlist while transcoding
2017-01-16 12:07:54.602372 I  Opening /var/lib/mythtv/recordings/1091_20161217175900.ts
2017-01-16 12:07:54.620403 I  PES packet size mismatch
2017-01-16 12:07:54.620416 I  PES packet size mismatch
2017-01-16 12:07:54.620441 I  Input #0, mpegts, from '/var/lib/mythtv/recordings/1091_20161217175900.ts':
2017-01-16 12:07:54.620451 I    Duration: 02:02:18.81, start: 14870.767044, bitrate: 18245 kb/s
2017-01-16 12:07:54.620504 I      Stream #0:0[0x31]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:07:54.620525 I      Stream #0:1[0x33](eng): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:07:54.620540 I      Stream #0:2[0x34](enm): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:07:54.625856 I  #0 PTS:04:07:51.113 Delta: 0.0ms queue: 14
2017-01-16 12:07:54.625881 I  #1 PTS:04:07:51.087 Delta: 26.8111ms queue: 6
2017-01-16 12:07:54.625891 I  #2 PTS:04:07:51.100 Delta: 13.5222ms queue: 2
2017-01-16 12:07:54.625921 N  MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers
<snipped out irrelevant parts of the output>
2017-01-16 12:13:36.032612 I  Generating Keyframe Index
2017-01-16 12:13:36.032627 I  Opening xxxa.mpg
2017-01-16 12:13:36.118553 I  Input #0, mpeg, from 'xxxa.mpg':
2017-01-16 12:13:36.118570 I    Duration: 01:24:11.71, start: 0.320078, bitrate: 17997 kb/s
2017-01-16 12:13:36.118617 I      Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:13:36.118637 I      Stream #0:1[0x81]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:13:36.118653 I      Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:15:53.743667 N  Transcode Completed
2017-01-16 12:15:53.936920 N  Transcoding /var/lib/mythtv/recordings/1091_20161217175900.ts done
Command:

Code: Select all

mythtranscode --chanid 1091 --starttime 20161217175900 --audiotrack 1 --honorcutlist -m -o xxxb.mpg
Output:

Code: Select all

2017-01-16 12:16:36.113758 C  mythtranscode version: fixes/0.28 [v0.28-100-g2d6466f] www.mythtv.org
2017-01-16 12:16:36.113778 C  Qt version: compile: 5.5.1, runtime: 5.5.1
2017-01-16 12:16:36.113783 N  Enabled verbose msgs:  general
2017-01-16 12:16:36.113792 N  Setting Log Level to LOG_INFO
2017-01-16 12:16:36.124435 I  Added logging to the console
2017-01-16 12:16:36.124814 I  Setup Interrupt handler
2017-01-16 12:16:36.124823 I  Setup Terminated handler
2017-01-16 12:16:36.124831 I  Setup Segmentation fault handler
2017-01-16 12:16:36.124836 I  Setup Aborted handler
2017-01-16 12:16:36.124843 I  Setup Bus error handler
2017-01-16 12:16:36.124849 I  Setup Floating point exception handler
2017-01-16 12:16:36.124855 I  Setup Illegal instruction handler
2017-01-16 12:16:36.124862 I  Setup Real-time signal 0 handler
2017-01-16 12:16:36.124871 I  Setup Hangup handler
2017-01-16 12:16:36.124961 N  Using runtime prefix = /usr
2017-01-16 12:16:36.124965 N  Using configuration directory = /home/brian/.mythtv
2017-01-16 12:16:36.125019 I  Assumed character encoding: en_CA.UTF-8
2017-01-16 12:16:36.125266 N  Empty LocalHostName.
2017-01-16 12:16:36.125271 I  Using localhost value of JACK
2017-01-16 12:16:36.155607 N  Setting QT default locale to en_CA
2017-01-16 12:16:36.155618 I  Current locale en_CA
2017-01-16 12:16:36.155659 N  Reading locale defaults from /usr/share/mythtv//locales/en_ca.xml
2017-01-16 12:16:36.161767 I  Loading en_ca translation for module mythfrontend
2017-01-16 12:16:36.164321 N  Transcoding from /var/lib/mythtv/recordings/1091_20161217175900.ts to xxxb.mpg
2017-01-16 12:16:36.164331 I  Honoring the cutlist while transcoding
2017-01-16 12:16:36.167912 I  Opening /var/lib/mythtv/recordings/1091_20161217175900.ts
2017-01-16 12:16:36.184341 I  PES packet size mismatch
2017-01-16 12:16:36.184353 I  PES packet size mismatch
2017-01-16 12:16:36.184376 I  Input #0, mpegts, from '/var/lib/mythtv/recordings/1091_20161217175900.ts':
2017-01-16 12:16:36.184384 I    Duration: 02:02:18.81, start: 14870.767044, bitrate: 18245 kb/s
2017-01-16 12:16:36.184433 I      Stream #0:0[0x31]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:16:36.184451 I      Stream #0:1[0x33](eng): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:16:36.184464 I      Stream #0:2[0x34](enm): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:16:36.189223 I  #0 PTS:04:07:51.113 Delta: 0.0ms queue: 14
2017-01-16 12:16:36.189245 I  #1 PTS:04:07:51.087 Delta: 26.8111ms queue: 6
2017-01-16 12:16:36.189254 I  #2 PTS:04:07:51.100 Delta: 13.5222ms queue: 2
2017-01-16 12:16:36.189281 N  MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers
<snipped out irrelevant parts of the output>
2017-01-16 12:22:05.572053 I  Generating Keyframe Index
2017-01-16 12:22:05.572067 I  Opening xxxb.mpg
2017-01-16 12:22:05.616765 I  Input #0, mpeg, from 'xxxb.mpg':
2017-01-16 12:22:05.616781 I    Duration: 01:24:11.71, start: 0.320078, bitrate: 17997 kb/s
2017-01-16 12:22:05.616824 I      Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:22:05.616843 I      Stream #0:1[0x81]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:22:05.616857 I      Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:24:23.051299 N  Transcode Completed
2017-01-16 12:24:23.180547 N  Transcoding /var/lib/mythtv/recordings/1091_20161217175900.ts done
Command:

Code: Select all

mythtranscode --chanid 1091 --starttime 20161217175900 --audiotrack 2 --honorcutlist -m -o xxxc.mpg
Output:

Code: Select all

2017-01-16 12:24:38.708272 C  mythtranscode version: fixes/0.28 [v0.28-100-g2d6466f] www.mythtv.org
2017-01-16 12:24:38.708293 C  Qt version: compile: 5.5.1, runtime: 5.5.1
2017-01-16 12:24:38.708298 N  Enabled verbose msgs:  general
2017-01-16 12:24:38.708308 N  Setting Log Level to LOG_INFO
2017-01-16 12:24:38.719109 I  Added logging to the console
2017-01-16 12:24:38.719558 I  Setup Interrupt handler
2017-01-16 12:24:38.719566 I  Setup Terminated handler
2017-01-16 12:24:38.719572 I  Setup Segmentation fault handler
2017-01-16 12:24:38.719580 I  Setup Aborted handler
2017-01-16 12:24:38.719585 I  Setup Bus error handler
2017-01-16 12:24:38.719592 I  Setup Floating point exception handler
2017-01-16 12:24:38.719598 I  Setup Illegal instruction handler
2017-01-16 12:24:38.719606 I  Setup Real-time signal 0 handler
2017-01-16 12:24:38.719616 I  Setup Hangup handler
2017-01-16 12:24:38.719712 N  Using runtime prefix = /usr
2017-01-16 12:24:38.719716 N  Using configuration directory = /home/brian/.mythtv
2017-01-16 12:24:38.719772 I  Assumed character encoding: en_CA.UTF-8
2017-01-16 12:24:38.720039 N  Empty LocalHostName.
2017-01-16 12:24:38.720044 I  Using localhost value of JACK
2017-01-16 12:24:38.776813 N  Setting QT default locale to en_CA
2017-01-16 12:24:38.776825 I  Current locale en_CA
2017-01-16 12:24:38.776894 N  Reading locale defaults from /usr/share/mythtv//locales/en_ca.xml
2017-01-16 12:24:38.785696 I  Loading en_ca translation for module mythfrontend
2017-01-16 12:24:38.788868 N  Transcoding from /var/lib/mythtv/recordings/1091_20161217175900.ts to xxxc.mpg
2017-01-16 12:24:38.788882 I  Honoring the cutlist while transcoding
2017-01-16 12:24:38.793161 I  Opening /var/lib/mythtv/recordings/1091_20161217175900.ts
2017-01-16 12:24:38.811922 I  PES packet size mismatch
2017-01-16 12:24:38.811937 I  PES packet size mismatch
2017-01-16 12:24:38.811964 I  Input #0, mpegts, from '/var/lib/mythtv/recordings/1091_20161217175900.ts':
2017-01-16 12:24:38.811975 I    Duration: 02:02:18.81, start: 14870.767044, bitrate: 18245 kb/s
2017-01-16 12:24:38.812033 I      Stream #0:0[0x31]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:24:38.812054 I      Stream #0:1[0x33](eng): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:24:38.812071 I      Stream #0:2[0x34](enm): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:24:38.818010 I  #0 PTS:04:07:51.113 Delta: 0.0ms queue: 14
2017-01-16 12:24:38.818036 I  #1 PTS:04:07:51.087 Delta: 26.8111ms queue: 6
2017-01-16 12:24:38.818046 I  #2 PTS:04:07:51.100 Delta: 13.5222ms queue: 2
2017-01-16 12:24:38.818078 N  MPEG2fixup::InitReplex(): High Definition input, increasing replex buffers
<snipped out irrelevant parts of the output>
2017-01-16 12:30:17.603744 I  Generating Keyframe Index
2017-01-16 12:30:17.603753 I  Opening xxxc.mpg
2017-01-16 12:30:17.694814 I  Input #0, mpeg, from 'xxxc.mpg':
2017-01-16 12:30:17.694828 I    Duration: 01:24:11.71, start: 0.320078, bitrate: 17997 kb/s
2017-01-16 12:30:17.694866 I      Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 17192 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
2017-01-16 12:30:17.694882 I      Stream #0:1[0x81]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
2017-01-16 12:30:17.694894 I      Stream #0:2[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
2017-01-16 12:32:36.532615 N  Transcode Completed
2017-01-16 12:32:36.713015 N  Transcoding /var/lib/mythtv/recordings/1091_20161217175900.ts done
It would appear that, at least with this particular file, there is no difference between the outputs while specifying different audio tracks.

I have tried multiple files and, while the results are not always the same as with this file, the --audiotrack option seems to have no effect whatsoever.

Is this a bug?

Brian

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

Re: mythtranscode --audiotrack ???

Post by daraden » Tue Jan 17, 2017 12:24 pm

tested --audiotrack and it fails to work for me as well. Also found why using the ts extension caused errors by default its still forcing mpeg (mpeg1 program stream) should be mpeg-ps (vob) for an mpeg2 program stream.
try adding

Code: Select all

-e ts
to your command

if that still not working give this a try

Code: Select all

#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
#MythTV commercial removal -- by Daraden
#usage userjob = /path to script/script.py --jobid %JOBID%
#/path to script/script.py --chanid --starttime can also be used
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
import logging.handlers
### user config###
#set this to True to use commflag results as cut list
use_commflag = False
#save copy of original file as file.old if not using output file
save_old = False
#user needs write access to this directory to save logfile
logdir ='/tmp/removecommercials/'
LOG_FILENAME = logdir+'cut.log'
##################
#logging setup for file and console
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
lf= logging.Formatter('%(asctime)s:%(levelname)s:%(message)s')
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(lf)
logger.addHandler(ch)
try:
    if not os.path.isdir(logdir):
        logging.info('Creating log directory')
        os.makedirs(logdir)
    if os.path.isdir(logdir):
        if os.access(logdir,os.W_OK):
            #fh = logging.FileHandler(filename='%scut.log'%(logdir),mode='w')
            fh = logging.handlers.TimedRotatingFileHandler(
                filename=LOG_FILENAME,when='W0',interval=1,
                backupCount=10)
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(lf)
            logger.addHandler(fh)
        if not os.access(logdir,os.W_OK):
            logging.error('logdir not accessible:%s',logdir)
        if not os.path.isdir(logdir):
            os.makedirs(logdir)
except Exception as e:
    logging.error('logdir not accessible:%s',logdir)
    logging.error(e)
    sys.exit(1)

try:
    db=MythDB()
except exception as e:
    logging.error(e)
    sys.exit(1)
    
def run_cut(jobid=None,chanid=None,starttime=None,outfile=None):
    logging.info('Started')
    #check for ffmpeg or mythffmpeg
    ffmpeg = prog_check()[0]
    ffprobe = prog_check()[1]
    logging.debug('ffmpeg=%s',ffmpeg)

    if jobid:
        job = Job(jobid, db=db)
        chanid = job.chanid
        starttime = job.starttime
        logging.debug('chanid=%s starttime=%s',chanid,starttime)
    if not jobid:
        chanid = chanid
        starttime = starttime
        logging.debug('chanid=%s starttime=%s',chanid,starttime)

    rec = find_rec(chanid,starttime)
    logging.debug('DB recording entry=%s',rec)
    sg = findfile('/%s' % (rec.basename), rec.storagegroup, db=db)
    infile = os.path.join(sg.dirname, rec.basename)
    tmpdir = '%scrtmp.%s/' % (sg.dirname, rec.basename.split('.')[0])
    logging.debug('tmpdir defined: %s',tmpdir)
    tmp_chk(tmpdir)

    if save_old == True and outfile == None:
        logging.info('Backing up original file: %s',infile)
        shutil.copyfile(infile,'%s.old' % infile)
        logging.info('Finished backing up original file: %s',infile)
    if outfile != None:
        Outfile = outfile
    if outfile == None:
        Outfile = infile

    if rec.cutlist == 1 or use_commflag == True:
        if use_commflag and not any([rec.commflagged, rec.cutlist]) :
            try:
                logging.info('Flagging commercials')
                startts = datetime.mythformat(rec.starttime)
                rst = subprocess.Popen(['mythcommflag','--chanid',
                                        str(chanid),'--starttime',
                                        str(startts)],
                                       stdout = subprocess.PIPE,
                                       stderr = subprocess.STDOUT)
                output2 = rst.communicate()[0]
                if rst.wait() == 0:
                    logging.info('Commercials flagged for:%s_%s',
                                 chanid,starttime)
                if rst.wait() != 0:
                    logging.error(
                        'MYTHcommflag ERROR: Flagging commercials for:\
                            %s_%s',chanid,starttime)
                    logging.error('%s',output2)
            except Exception as e:
                logging.error('Mythcommflag ERROR: Flagging commercials\
                                %s',e)
            rec = find_rec(chanid,starttime)
        if jobid:
            job.update({'status':job.RUNNING,
                        'comment':'Removing Cutlist'})
        logging.info('getting cutlist')
        if rec.cutlist == 1:
            cut_list = (','.join(
                [','.join(str(i) for i in b)
                 for b in rec.markup.getcutlist()]))
        elif rec.cutlist == 0 and rec.commflagged == 1:
            cut_list = (','.join(
                [','.join(str(i) for i in b)
                 for b in rec.markup.getskiplist()]))
        else:
            logging.debug('No cut/skip list found')
            sys.exit(1)            
        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')
        cmd = [ffmpeg,'-i',infile,'-c','copy','-map','0']
        av_check = av_info(ffprobe,infile)
        if len(av_check.audio) > 1:
            for s0 in av_check.audio:
                if s0.get('channels') == '0':
                    cmd.extend(('-map',('-0:' + s0.get('index'))))

        cmd.extend(('-f','segment','-segment_list',
                    '%scut.ffcat'%(tmpdir),'-segment_frames',cutlist,
                    '%scut%%03d.ts'%(tmpdir)))
        cut =subprocess.Popen(cmd,stdout = subprocess.PIPE,
                              stderr = subprocess.STDOUT,
                              universal_newlines=True)
        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',
                                Outfile],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(1)
    rem_tmp(tmpdir)
    if  outfile == None:
        clear_markup(rec,infile,outfile)
    if jobid:
        job.update({'status':job.FINISHED,
                    'comment':'Commercial removal Completed'})


def clear_markup(rec,infile,outfile):
    logging.info('Started Clearing markup')
    
    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)
        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)
        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(infile)
    rec.filesize = os.path.getsize(infile)
    rec.transcoded = 1
    rec.seek.clean()
    rec.update()
    
    try:
        logging.info('Removing PNG files')
        for png in glob('%s*.png' % infile):
            os.remove(png)
    except Exception as e:
        logging.error('Error removing png files',e)
    try:
        logging.info('Removing JPG files')
        for jpg in glob('%s*.jpg' % infile):
            os.remove(jpg)
    except Exception as e:
        logging.error('Error removing jpg files',e)    
    try:
        logging.info('Rebuilding seektable')
        rst = subprocess.Popen(['mythcommflag','--chanid',str(chanid),
                                '--starttime',str(starttime),
                                '--rebuild'], stdout = subprocess.PIPE,
                               stderr = subprocess.STDOUT)
        output2 = rst.communicate()[0]
        if rst.wait() == 0:
            logging.info('Seektable Rebuilt for:%s_%s',chanid,starttime)
        if rst.wait() != 0:
            logging.error(
                'MYTHcommflag ERROR: Rebuilding Seektable for:%s_%s',
                chanid,starttime)
            logging.error('%s',output2)
    except Exception as e:
        logging.error('Mythcommflag ERROR clearing skiplist:%s',e)

def tmp_chk(tmpdir):
        try:
            if os.path.isdir(tmpdir):
                logging.info('chk:temp Folder found: %s',tmpdir)
                if os.listdir(tmpdir) != 0:
                    logging.warning(
                        'chk:Temp folder not empty!:Removing Files: %s',
                        tmpdir)
                    shutil.rmtree(tmpdir)
                    os.makedirs(tmpdir)
            if not os.path.isdir(tmpdir):
                logging.info('chk:no temp folder found: %s',tmpdir)
                os.makedirs(tmpdir)
                logging.info('chk:Temp folder created: %s',tmpdir)
        except Exception as e:
            logging.error('%s',e)
def rem_tmp(tmpdir):
            try:
                if os.path.isdir(tmpdir):
                    logging.info('rem:temp Folder found %s',tmpdir)
                    shutil.rmtree(tmpdir)
                if not os.path.isdir(tmpdir):
                    logging.info('rem:temp Folder Removed %s',tmpdir)
            except Exception as e:
                logging.error('%s',e)
def find_rec(chanid,starttime):
    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 RecordedFromBasename(chanid,starttime):
        bnts = '%s_%s.ts' % (chanid,starttime)
        bnmpg = '%s_%s.mpg' % (chanid,starttime)

        x = list(db.searchRecorded(basename=bnmpg))
        if len(x) == 1:
            for recorded in x:
                return recorded
                
        if len(x) != 1:
            x = list(db.searchRecorded(basename=bnts))
            if len(x) == 1:
                for recorded in x:
                    return recorded
            if len(x) != 1:    
                raise LookupError\
        ('unable to find Recorded entry for ChanID %s StartTime %s'\
         % (chanid,starttime))
    try:
        rec = Recorded((chanid,starttime), db=db)
    except:        
        try:
            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)
        except:
            rec = RecordedFromBasename(chanid,starttime)
    return rec
def run(command):
    exe = subprocess.Popen(command,stdout =
        subprocess.PIPE, stderr = subprocess.STDOUT)
    return exe.communicate()[0].split('\n')
class av_info:
    #identify A/V configuration of input file and returns self.video dict
    #a list of audio stream dicts, self.duration as float
    def __init__(self=None,ffprobe=None,infile=None):
        class Bunch(object):
            def __init__(self, adict):
                self.__dict__.update(adict)
        command = [ffprobe,'-v','-8','-show_entries','stream=codec_type,\
                    index,codec_name,channels,width,height,r_frame_rate\
                    :stream_tags=language:format=duration','-of',
                   'csv=nk=0:p=0',infile]
        x = run(command)
        asl = []
        vcd = {}
        for vc in x:
            if 'codec_type=video' in vc:
                for item in vc.split(','):
                    k,v = item.split('=')
                    vcd.update({k:v})
        for ac in x:
            if 'codec_type=audio' in ac:        
                al =[]
                al.append(ac)
                for s in al:
                    mydict = dict((k.strip(), v.strip()) for k,v in (
                        item.split('=') for item in s.split(',')))
                    asl.append(mydict)
        for d in x:
            if d.startswith('duration='):
                dur = dict({d.split('=')[0]:d.split('=')[1]})
        for stream in asl:
            if 'tag:language' in stream.keys():
                stream['language'] = stream.pop('tag:language')
                
            if stream.get('index') == '1':
                self.audio_s1 = Bunch(stream)
            if stream.get('index') == '2':
                self.audio_s2 = Bunch(stream)
        
        self.video = Bunch(vcd)
        self.audio = asl
        self.duration = dur.values()[0]
def prog_check():
    #checks for FFmpeg/FFprobe
    #if not found MythFFmpeg/MythFFprobe is used
    from distutils import spawn

    if spawn.find_executable('ffmpeg') != None:
        ffmpeg = spawn.find_executable('ffmpeg')
    elif (spawn.find_executable('ffmpeg') == None and
          spawn.find_executable('mythffmpeg')):
        ffmpeg = spawn.find_executable('mythffmpeg')
    else:        ffmpeg = None
    if spawn.find_executable('ffprobe') != None:
        ffprobe = spawn.find_executable('ffprobe')
    elif (spawn.find_executable('ffprobe') == None and
          spawn.find_executable('mythffprobe')):
        ffprobe = spawn.find_executable('mythffprobe')
    else:
        ffprobe = None
    if ffmpeg != None and ffprobe != None:
        return ffmpeg,ffprobe
    else:
        raise LookupError('Unable to find FFmpeg or MythFFmpeg')
def main():
    parser = argparse.ArgumentParser(
        description='MythTV Commercial removal')
    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('-o',action='store',type=str,dest='outfile',
                        help='Output file to be created')
    args = parser.parse_args()
    if args.jobid:
        run_cut(jobid=args.jobid,outfile=args.outfile)
        sys.exit(0)        
    if args.chanid and args.starttime:
        run_cut(chanid=args.chanid,starttime=args.starttime,
                outfile=args.outfile)
        sys.exit(0)
    else:
        print 'chanid and starttime or jobid required'
main()
only removes commercials
can be run with -o <output file>, otherwise it cuts the original file.

bpmod
Junior
Posts: 27
Joined: Fri Mar 25, 2016 3:42 pm
Canada

Re: mythtranscode --audiotrack ???

Post by bpmod » Thu Jan 19, 2017 4:29 am

daraden wrote:tested --audiotrack and it fails to work for me as well. Also found why using the ts extension caused errors by default its still forcing mpeg (mpeg1 program stream) should be mpeg-ps (vob) for an mpeg2 program stream.
try adding

Code: Select all

-e ts
to your command
I wasn't simply using the extension ts and hoping that that's what I'd get. I was using the -e switch as you suggest. The errors seem to be caused by the audio stream being somehow identified (by ffmpeg in the next step of my script) as a second video stream. Major wonkiness.

I guess it's back to transcoding my few hundred shows manually as I find the time.

I was hoping that some of the developers of MythTV hung out here.

Brian

Post Reply