Adding an option to dump images of trailers and headers of each part for debugging purpose.
This commit is contained in:
58
removeads.py
58
removeads.py
@@ -359,7 +359,9 @@ def extractPictures(inputFile, begin, nbFrames, width=640, height=480):
|
|||||||
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:
|
||||||
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:
|
if fdr in fds:
|
||||||
buf = os.read(fdr, 1000000)
|
buf = os.read(fdr, 1000000)
|
||||||
# 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()))
|
||||||
@@ -415,11 +417,47 @@ def extractSound(inputFile, begin, outputFile, subChannel=0, nbPackets=0, sample
|
|||||||
if status != 0:
|
if status != 0:
|
||||||
logger.error('Sound extraction returns error code: %d' % status)
|
logger.error('Sound extraction returns error code: %d' % status)
|
||||||
|
|
||||||
def dumpPPM(pictures, prefix):
|
def dumpPPM(pictures, prefix, temporaries):
|
||||||
# "P6\nWIDTH HEIGHT\n255\n"
|
logger = logging.getLogger(__name__)
|
||||||
# headerLen=2+1+ceil(log(width, 10))+1+ceil(log(height, 10))+1+3+1
|
|
||||||
pass
|
# "P6\nWIDTH HEIGHT\n255\n"
|
||||||
|
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):
|
def extractAllStreams(inputFile, begin, end, streams, filesPrefix, nbFrames, width, height, temporaries, dumpPictures=False):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
# encoderParams = [ 'ffmpeg', '-y', '-loglevel', 'quiet' ]
|
# encoderParams = [ 'ffmpeg', '-y', '-loglevel', 'quiet' ]
|
||||||
@@ -460,7 +498,7 @@ def extractAllStreams(inputFile, begin, end, streams, filesPrefix, nbFrames, wid
|
|||||||
codec = stream['codec_name']
|
codec = stream['codec_name']
|
||||||
imagesBytes = extractPictures(inputFile=inputFile, begin=begin, nbFrames=nbFrames, width=width, height=height)
|
imagesBytes = extractPictures(inputFile=inputFile, begin=begin, nbFrames=nbFrames, width=width, height=height)
|
||||||
if dumpPictures:
|
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.
|
# imagesBytes contains now a buffer of bytes that represents the pictures that have been dumped by ffmpeg.
|
||||||
fdr, fdw = os.pipe()
|
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("-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', 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()
|
args = parser.parse_args()
|
||||||
logger.debug("Arguments: %s" % args)
|
logger.debug("Arguments: %s" % args)
|
||||||
@@ -782,7 +820,7 @@ def main():
|
|||||||
|
|
||||||
if nbHeadFrames > 0:
|
if nbHeadFrames > 0:
|
||||||
# We extract all frames between the beginning upto the frame that immediately preceeds the I-frame.
|
# 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)
|
subparts.append(head)
|
||||||
|
|
||||||
# Creating MKV file that corresponds to current part between I-frames
|
# Creating MKV file that corresponds to current part between I-frames
|
||||||
@@ -797,7 +835,7 @@ def main():
|
|||||||
|
|
||||||
if nbTailFrames > 0:
|
if nbTailFrames > 0:
|
||||||
# We extract all frames between the I-frame (including it) upto the end.
|
# 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)
|
subparts.append(tail)
|
||||||
|
|
||||||
logger.info('Merging: %s' % subparts)
|
logger.info('Merging: %s' % subparts)
|
||||||
|
|||||||
Reference in New Issue
Block a user