Adding an option to dump images of trailers and headers of each part for debugging purpose.
This commit is contained in:
54
removeads.py
54
removeads.py
@@ -359,7 +359,9 @@ def extractPictures(inputFile, begin, nbFrames, width=640, height=480):
|
||||
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:
|
||||
while ffmpeg.poll() == None:
|
||||
fds, _, _ = select([fdr, ffmpeg.stdout], [], [], .1)
|
||||
# TODO: understand why this line ends up in reading on an already closed file descriptor
|
||||
# fds, _, _ = select([fdr, ffmpeg.stdout], [], [], .1)
|
||||
fds, _, _ = select([fdr], [], [], .1)
|
||||
if fdr in fds:
|
||||
buf = os.read(fdr, 1000000)
|
||||
# print("Read %d bytes of image. ffmpeg finished: %s" % (len(buf), ffmpeg.poll()))
|
||||
@@ -415,10 +417,46 @@ def extractSound(inputFile, begin, outputFile, subChannel=0, nbPackets=0, sample
|
||||
if status != 0:
|
||||
logger.error('Sound extraction returns error code: %d' % status)
|
||||
|
||||
def dumpPPM(pictures, prefix):
|
||||
def dumpPPM(pictures, prefix, temporaries):
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# "P6\nWIDTH HEIGHT\n255\n"
|
||||
# headerLen=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1
|
||||
pass
|
||||
pos = 0
|
||||
picture = 0
|
||||
while pos<len(pictures):
|
||||
filename = '%s-%03d.ppm' % (prefix, picture)
|
||||
header = BytesIO(pictures[pos:])
|
||||
magic = header.readline().decode('utf8')
|
||||
dimensions = header.readline().decode('utf8')
|
||||
maxvalue = header.readline().decode('utf8')
|
||||
if magic == 'P6\n':
|
||||
pattern = re.compile('^(?P<width>[0-9]+) (?P<height>[0-9]+)\n$')
|
||||
m = pattern.match(dimensions)
|
||||
if m != None:
|
||||
width = int(m['width'])
|
||||
height = int(m['height'])
|
||||
else:
|
||||
logger.error('Impossible to parse dimensions of picture')
|
||||
return
|
||||
else:
|
||||
logger.error('Not a PPM picture')
|
||||
return
|
||||
|
||||
headerLen=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1
|
||||
try:
|
||||
out = open(filename, 'w')
|
||||
outfd = out.fileno()
|
||||
except IOError:
|
||||
logger.error('Impossible to create file: %s' % filename)
|
||||
temporaries.append(out)
|
||||
|
||||
length=headerLen+3*width*height
|
||||
nbBytes = 0
|
||||
while nbBytes < length:
|
||||
nbBytes+=os.write(outfd, pictures[pos+nbBytes:pos+length])
|
||||
pos+=length
|
||||
picture+=1
|
||||
|
||||
|
||||
def extractAllStreams(inputFile, begin, end, streams, filesPrefix, nbFrames, width, height, temporaries, dumpPictures=False):
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -460,7 +498,7 @@ def extractAllStreams(inputFile, begin, end, streams, filesPrefix, nbFrames, wid
|
||||
codec = stream['codec_name']
|
||||
imagesBytes = extractPictures(inputFile=inputFile, begin=begin, nbFrames=nbFrames, width=width, height=height)
|
||||
if dumpPictures:
|
||||
dumpPPM(imagesBytes, '%s-%d' % (filesPrefix,videoID))
|
||||
dumpPPM(imagesBytes, '%s-%d' % (filesPrefix,videoID), temporaries)
|
||||
|
||||
# imagesBytes contains now a buffer of bytes that represents the pictures that have been dumped by ffmpeg.
|
||||
fdr, fdw = os.pipe()
|
||||
@@ -634,7 +672,7 @@ def main():
|
||||
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("-k", "--keep", action='store_true', help="Do not cleanup temporary files after processing.")
|
||||
parser.add_argument("--dump-pictures", action='store_true', 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.")
|
||||
|
||||
args = parser.parse_args()
|
||||
logger.debug("Arguments: %s" % args)
|
||||
@@ -782,7 +820,7 @@ def main():
|
||||
|
||||
if nbHeadFrames > 0:
|
||||
# We extract all frames between the beginning upto the frame that immediately preceeds the I-frame.
|
||||
head = extractAllStreams(inputFile=mkv, begin=ts1, end=headIFrameTS, nbFrames=nbHeadFrames-1, filesPrefix='part-%d-head' % (partnum), streams=streams, width=width, height=height, temporaries=temporaries)
|
||||
head = extractAllStreams(inputFile=mkv, begin=ts1, end=headIFrameTS, nbFrames=nbHeadFrames-1, filesPrefix='part-%d-head' % (partnum), streams=streams, width=width, height=height, temporaries=temporaries, dumpPictures=args.dump)
|
||||
subparts.append(head)
|
||||
|
||||
# Creating MKV file that corresponds to current part between I-frames
|
||||
@@ -797,7 +835,7 @@ def main():
|
||||
|
||||
if nbTailFrames > 0:
|
||||
# We extract all frames between the I-frame (including it) upto the end.
|
||||
tail = extractAllStreams(inputFile=mkv, begin=tailIFrameTS, end=ts2, nbFrames=nbTailFrames, filesPrefix='part-%d-tail' % (partnum), streams=streams, width=width, height=height, temporaries=temporaries)
|
||||
tail = extractAllStreams(inputFile=mkv, begin=tailIFrameTS, end=ts2, nbFrames=nbTailFrames, filesPrefix='part-%d-tail' % (partnum), streams=streams, width=width, height=height, temporaries=temporaries, dumpPictures=args.dump)
|
||||
subparts.append(tail)
|
||||
|
||||
logger.info('Merging: %s' % subparts)
|
||||
|
||||
Reference in New Issue
Block a user