Compare commits
4 Commits
22592214bb
...
58ec094cfc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58ec094cfc | ||
|
|
0f46dc9fda | ||
|
|
cf4850c8dc | ||
|
|
ed0494b540 |
83
removeads.py
83
removeads.py
@@ -26,11 +26,15 @@ from shutil import copyfile, which
|
|||||||
|
|
||||||
def checkRequiredTools():
|
def checkRequiredTools():
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
tools = ['ffmpeg', 'ffprobe', 'mkvmerge']
|
required = ['ffmpeg', 'ffprobe', 'mkvmerge']
|
||||||
for tool in tools:
|
optional = ['mkvextract', 'vobusbocr']
|
||||||
|
for tool in required:
|
||||||
if which(tool) == None:
|
if which(tool) == None:
|
||||||
logger.error('Required tool: %s is missing.' % tool)
|
logger.error('Required tool: %s is missing.' % tool)
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
for tool in optional:
|
||||||
|
if which(tool) == None:
|
||||||
|
logger.info('Optional tool: %s is missing.' % tool)
|
||||||
|
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
@@ -49,6 +53,11 @@ class SupportedFormat(IntEnum):
|
|||||||
else:
|
else:
|
||||||
return 'Unsupported format'
|
return 'Unsupported format'
|
||||||
|
|
||||||
|
# Extract SPS/PPS
|
||||||
|
# https://gitlab.com/mbunkus/mkvtoolnix/-/issues/2390
|
||||||
|
# ffmpeg -i <InputFile (before concatenation)> -c:v copy -an -sn -bsf:v trace_headers -t 0.01 -report -loglevel 0 -f null -
|
||||||
|
|
||||||
|
|
||||||
def getFormat(inputFile):
|
def getFormat(inputFile):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -352,10 +361,11 @@ def extractPictures(inputFile, begin, nbFrames, width=640, height=480):
|
|||||||
# "P6\nWIDTH HEIGHT\n255\n"
|
# "P6\nWIDTH HEIGHT\n255\n"
|
||||||
headerLen=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1
|
headerLen=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1
|
||||||
logger.debug('Header length: %d' % headerLen)
|
logger.debug('Header length: %d' % headerLen)
|
||||||
length = (width*height*3+headerLen)*nbFrames
|
imageLength = width*height*3+headerLen
|
||||||
|
length = imageLength*nbFrames
|
||||||
logger.debug("Estimated length: %d" % length)
|
logger.debug("Estimated length: %d" % length)
|
||||||
|
|
||||||
pg = trange(length)
|
pg = trange(nbFrames)
|
||||||
images = bytes()
|
images = bytes()
|
||||||
with Popen(['ffmpeg', '-loglevel', 'quiet' ,'-y', '-ss', '%s'%begin, '-i', '/proc/self/fd/%d' % infd, '-s', '%dx%d'%(width, height), '-vframes', '%d'%nbFrames, '-c:v', 'ppm', '-f', 'image2pipe', '/proc/self/fd/%d' % fdw ], stdout=PIPE, close_fds=False) as ffmpeg:
|
with Popen(['ffmpeg', '-loglevel', 'quiet' ,'-y', '-ss', '%s'%begin, '-i', '/proc/self/fd/%d' % infd, '-s', '%dx%d'%(width, height), '-vframes', '%d'%nbFrames, '-c:v', 'ppm', '-f', 'image2pipe', '/proc/self/fd/%d' % fdw ], stdout=PIPE, close_fds=False) as ffmpeg:
|
||||||
while ffmpeg.poll() == None:
|
while ffmpeg.poll() == None:
|
||||||
@@ -363,11 +373,11 @@ def extractPictures(inputFile, begin, nbFrames, width=640, height=480):
|
|||||||
# fds, _, _ = select([fdr, ffmpeg.stdout], [], [], .1)
|
# fds, _, _ = select([fdr, ffmpeg.stdout], [], [], .1)
|
||||||
fds, _, _ = select([fdr], [], [], .1)
|
fds, _, _ = select([fdr], [], [], .1)
|
||||||
if fdr in fds:
|
if fdr in fds:
|
||||||
buf = os.read(fdr, 1000000)
|
buf = os.read(fdr, imageLength)
|
||||||
# print("Read %d bytes of image. ffmpeg finished: %s" % (len(buf), ffmpeg.poll()))
|
# print("Read %d bytes of image. ffmpeg finished: %s" % (len(buf), ffmpeg.poll()))
|
||||||
if len(buf) == 0:
|
if len(buf) == 0:
|
||||||
break
|
break
|
||||||
pg.update(len(buf))
|
pg.update(len(buf)/imageLength)
|
||||||
images=images+buf
|
images=images+buf
|
||||||
if ffmpeg.stdout in fds:
|
if ffmpeg.stdout in fds:
|
||||||
for line in TextIOWrapper(ffmpeg.stdout, encoding="utf-8"):
|
for line in TextIOWrapper(ffmpeg.stdout, encoding="utf-8"):
|
||||||
@@ -379,11 +389,11 @@ def extractPictures(inputFile, begin, nbFrames, width=640, height=480):
|
|||||||
while True:
|
while True:
|
||||||
fd, _, _ = select([fdr], [], [], .1)
|
fd, _, _ = select([fdr], [], [], .1)
|
||||||
if fd != []:
|
if fd != []:
|
||||||
buf = os.read(fdr, 1000000)
|
buf = os.read(fdr, imageLength)
|
||||||
# print("Read %d bytes of image" % len(buf))
|
# print("Read %d bytes of image" % len(buf))
|
||||||
if len(buf) == 0:
|
if len(buf) == 0:
|
||||||
break
|
break
|
||||||
pg.update(len(buf))
|
pg.update(len(buf)/imageLength)
|
||||||
images=images+buf
|
images=images+buf
|
||||||
else:
|
else:
|
||||||
# Nothing more to read
|
# Nothing more to read
|
||||||
@@ -661,8 +671,30 @@ def mergeMKVs(inputs, outputName):
|
|||||||
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
def findSubtitlesTracks(filename):
|
||||||
|
# ffprobe -loglevel quiet -select_streams s -show_entries stream=index:stream_tags=language -of json corgi.ts
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
with Popen(['ffprobe', '-i', filename, '-select_streams', 's', '-show_entries', 'stream=index:stream_tags=language', '-of', 'json'], stdout=PIPE, close_fds=False) as ffprobe:
|
||||||
|
out, _ = ffprobe.communicate()
|
||||||
|
out = json.load(BytesIO(out))
|
||||||
|
if 'streams' in out:
|
||||||
|
return out['streams']
|
||||||
|
else:
|
||||||
|
logger.error('Impossible to retrieve format of file')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def extractSubTitleTrack(inputFileName, index, lang):
|
||||||
|
# mkvextract video.mkv tracks position:nom [position:nom]
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
with Popen(['mkvextract', inputFileName, 'tracks', '%d:%s' % (index,lang)], stdout=PIPE, close_fds=False) as mkvextract:
|
||||||
|
out, _ = mkvextract.communicate()
|
||||||
|
for lines in out:
|
||||||
|
logger.info(out)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
coloredlogs.install()
|
coloredlogs.install()
|
||||||
@@ -672,7 +704,8 @@ def main():
|
|||||||
parser.add_argument("-o", "--output", dest='outputFile', type=str, required=True, help="Output MKV file to produce.")
|
parser.add_argument("-o", "--output", dest='outputFile', type=str, required=True, help="Output MKV file to produce.")
|
||||||
parser.add_argument("-p", "--part", dest='parts', nargs='+', required=False, action='append', metavar="hh:mm:ss[.mmm]-hh:mm:ss[.mmm]", help="Extract this exact part of the original file.")
|
parser.add_argument("-p", "--part", dest='parts', nargs='+', required=False, action='append', metavar="hh:mm:ss[.mmm]-hh:mm:ss[.mmm]", help="Extract this exact part of the original file.")
|
||||||
parser.add_argument("-k", "--keep", action='store_true', help="Do not cleanup temporary files after processing.")
|
parser.add_argument("-k", "--keep", action='store_true', help="Do not cleanup temporary files after processing.")
|
||||||
parser.add_argument("--dump-pictures", action='store_true', dest='dump', help="For debug purpose, dump pictures of headers (and trailers) before (after) each part. They are kept in memory only otherwise.")
|
parser.add_argument("--dump-pictures", action='store_true', dest='dump', help="For debug purpose, dump pictures of headers (and trailers) before (after) each part. They are kept in memory only otherwise.")
|
||||||
|
parser.add_argument("-s","--srt", action='store_true', dest='srt', help="Dump subtitles ")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
logger.debug("Arguments: %s" % args)
|
logger.debug("Arguments: %s" % args)
|
||||||
@@ -857,6 +890,38 @@ def main():
|
|||||||
else:
|
else:
|
||||||
logger.info("Nothing else to do.")
|
logger.info("Nothing else to do.")
|
||||||
|
|
||||||
|
if args.srt:
|
||||||
|
logger.info("Find subtitles tracks and language.")
|
||||||
|
subtitles = findSubtitlesTracks(args.outputFile)
|
||||||
|
sts = {}
|
||||||
|
for subtitle in subtitles:
|
||||||
|
index = subtitle['index']
|
||||||
|
if 'tags' in subtitle:
|
||||||
|
if 'language' in subtitle['tags']:
|
||||||
|
lang = subtitle['tags']['language']
|
||||||
|
if lang in sts:
|
||||||
|
sts[lang].append(index)
|
||||||
|
else:
|
||||||
|
sts[lang] = [index]
|
||||||
|
else:
|
||||||
|
logger.error("Dropping subtitle: %s because it is missing language indication")
|
||||||
|
else:
|
||||||
|
logger.error("Dropping subtitle: %s because it is missing language indication")
|
||||||
|
|
||||||
|
for lang in sts:
|
||||||
|
indexes = sts[lang]
|
||||||
|
if len(indexes) == 0:
|
||||||
|
# Nothing to do. This should not happen.
|
||||||
|
continue
|
||||||
|
if len(indexes) == 1:
|
||||||
|
index = indexes[0]
|
||||||
|
filename = 'essai-%s.srt' % lang
|
||||||
|
elif len(indexes) > 1:
|
||||||
|
nbsrt = 1
|
||||||
|
for index in indexes:
|
||||||
|
filename = 'essai-%s-%d.srt' % (lang, nbsrt)
|
||||||
|
nbsrt+=1
|
||||||
|
|
||||||
if not args.keep:
|
if not args.keep:
|
||||||
logger.info("Cleaning temporary files")
|
logger.info("Cleaning temporary files")
|
||||||
for f in temporaries:
|
for f in temporaries:
|
||||||
|
|||||||
Reference in New Issue
Block a user