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() |     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,10 +417,46 @@ 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): | ||||||
|  |     logger = logging.getLogger(__name__) | ||||||
|  |      | ||||||
|     # "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 |     pos = 0 | ||||||
|     pass |     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__) | ||||||
| @@ -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