Inner parts ared dumped as MKV. Head and tail of each part are dumped for video and sound.
This commit is contained in:
		
							
								
								
									
										94
									
								
								removeads.py
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								removeads.py
									
									
									
									
									
								
							| @@ -104,22 +104,61 @@ def getNearestIFrame(inputFile, timestamp, before=True, delta=timedelta(seconds= | ||||
|             for frame in iframes:  | ||||
|                 if before and timedelta(seconds=float(frame['pts_time'])) <= timestamp: | ||||
|                     found = True | ||||
|                     res = frame | ||||
|                     iframe = frame | ||||
|                 if not before and timedelta(seconds=float(frame['pts_time'])) >= timestamp: | ||||
|                     found = True | ||||
|                     res = frame | ||||
|                     iframe = frame | ||||
|                     break | ||||
|  | ||||
|             if found: | ||||
|                 logger.debug("Found: %s" % res) | ||||
|                  | ||||
|                 its = timedelta(seconds=float(iframe['pts_time']))  | ||||
|                 nbFrames = 0 | ||||
|                 for frame in frames: | ||||
|                     ts = timedelta(seconds=float(frame['pts_time']))  | ||||
|                     if before: | ||||
|                         if its <= ts and ts <= timestamp: | ||||
|                             nbFrames = nbFrames+1 | ||||
|                     else: | ||||
|                         if timestamp <= ts and ts <= its: | ||||
|                             nbFrames = nbFrames+1 | ||||
|             else: | ||||
|                 logger.error("Impossible to find I-frame around: %s" % timestamp) | ||||
|             return(res) | ||||
|              | ||||
|             return(nbFrames-1, iframe) | ||||
|         else: | ||||
|            logger.error('Impossible to retrieve video frames inside file around [%s,%s]' % (tbegin, tend))  | ||||
|  | ||||
|     return None | ||||
|      | ||||
|  | ||||
| def extractMKVPart(inputFile, outputFile, begin, end): | ||||
|     inputFile.seek(0,0) | ||||
|     outputFile.seek(0,0) | ||||
|     infd = inputFile.fileno() | ||||
|     outfd = outputFile.fileno() | ||||
|     set_inheritable(infd, True) | ||||
|     set_inheritable(outfd, True) | ||||
|     with Popen(['mkvmerge', '-o', '/proc/self/fd/%d' % outfd, '--split', 'parts:%s-%s' % (begin, end), '/proc/self/fd/%d' % infd], stdout=PIPE, close_fds=False) as mkvmerge: | ||||
|         for line in TextIOWrapper(mkvmerge.stdout, encoding="utf-8"): | ||||
|             print(line, end='') | ||||
|  | ||||
| def extractPictures(inputFile, begin, nbFrames, prefix, width=640, height=480): | ||||
|     inputFile.seek(0,0) | ||||
|     infd = inputFile.fileno() | ||||
|     set_inheritable(infd, True) | ||||
|     with Popen(['ffmpeg', '-loglevel', 'quiet', '-ss', '%s'%begin, '-i', '/proc/self/fd/%d' % infd, '-s', '%dx%d'%(width, height), '-vframes', '%d'%nbFrames, '-c:v', 'ppm', '-f', 'image2', '%s-%%03d.ppm' % prefix], stdout=PIPE, close_fds=False) as ffmpeg: | ||||
|         for line in TextIOWrapper(ffmpeg.stdout, encoding="utf-8"): | ||||
|             print(line, end='') | ||||
|  | ||||
| def extractSound(inputFile, begin, outputFile, channel=0, nbPackets=10, sampleRate=48000, nbChannels=2): | ||||
|     inputFile.seek(0,0) | ||||
|     infd = inputFile.fileno() | ||||
|     set_inheritable(infd, True) | ||||
|     with Popen(['ffmpeg', '-loglevel', 'quiet', '-ss', '%s'%begin, '-i', '/proc/self/fd/%d' % infd, '-frames:a:%d' % channel, '%d' % nbPackets,  | ||||
|                 '-c:a', 'pcm_s32le', '-sample_rate', '%d' % 48000, '-channels', '%d' % 2, '-f', 's32le', '%s.pcm' % outputFile], stdout=PIPE, close_fds=False) as ffmpeg: | ||||
|         for line in TextIOWrapper(ffmpeg.stdout, encoding="utf-8"): | ||||
|             print(line, end='') | ||||
|  | ||||
| def parseTimeInterval(interval): | ||||
|     logger = logging.getLogger(__name__) | ||||
| @@ -287,6 +326,8 @@ def main(): | ||||
|     for stream in streams: | ||||
|         if stream['codec_type'] == 'video' and stream['disposition']['default'] == 1: | ||||
|             mainVideo = stream | ||||
|             width = stream['width'] | ||||
|             height = stream['height'] | ||||
|      | ||||
|     if mainVideo == None: | ||||
|         logger.error('Impossible to find main video stream.') | ||||
| @@ -305,17 +346,50 @@ def main(): | ||||
|         if postFrame == None: | ||||
|             exit(-1) | ||||
|          | ||||
|         nbPreFrame, preIFrame = preFrame | ||||
|         nbPostFrame, postIFrame = postFrame | ||||
|          | ||||
|         print(preFrame) | ||||
|         print(postFrame) | ||||
|         print("Found pre I-frame and %d frames between: %s" % (nbPreFrame, preIFrame)) | ||||
|         print("Found I-frame and %d frames between: %s" % (nbPostFrame, postIFrame)) | ||||
|          | ||||
|         if timedelta(seconds=float(preFrame['pts_time'])) == ts1: | ||||
|         preIFrameTS = timedelta(seconds=float(preIFrame['pts_time'])) | ||||
|         postIFrameTS = timedelta(seconds=float(postIFrame['pts_time'])) | ||||
|          | ||||
|         if ts1 < preIFrameTS: | ||||
|             for stream in streams: | ||||
|                 if stream['codec_type'] == 'video': | ||||
|                     extractPictures(inputFile=mkv, begin=ts1, nbFrames=nbPreFrame, prefix="pre-part-%d" % partnum, width=width, height=height) | ||||
|                 elif stream['codec_type'] == 'audio': | ||||
|                     print("Extracting audio stream: %s" % stream) | ||||
|                     sampleRate = stream['sample_rate'] | ||||
|                     nbChannel = stream['channels'] | ||||
|                     extractSound(inputFile=mkv, begin=ts1, nbPackets=nbPreFrame, outputFile="pre-part-%d" % partnum, sampleRate=sampleRate, nbChannels=nbChannels) | ||||
|                 else: | ||||
|                     pass | ||||
|         else: | ||||
|             # Nothing to do | ||||
|             pass | ||||
|          | ||||
|         if postIFrameTS < ts2: | ||||
|             for stream in streams: | ||||
|                 if stream['codec_type'] == 'video': | ||||
|                     extractPictures(inputFile=mkv, begin=postIFrameTS, nbFrames=nbPostFrame, prefix="post-part-%d" % partnum, width=width, height=height) | ||||
|                 elif stream['codec_type'] == 'audio': | ||||
|                     print("Extracting audio stream: %s" % stream) | ||||
|                     sampleRate = stream['sample_rate'] | ||||
|                     nbChannel = stream['channels'] | ||||
|                     # TODO: how many packets should be dumped ... | ||||
|                     # TODO: take into account multiple sound tracks ... | ||||
|                     extractSound(inputFile=mkv, begin=postIFrameTS, nbPackets=nbPostFrame, outputFile="post-part-%d" % partnum, sampleRate=sampleRate, nbChannels=nbChannels) | ||||
|                 else: | ||||
|                     pass | ||||
|         else: | ||||
|             # Nothing to do ! | ||||
|             pass | ||||
|          | ||||
|         if timedelta(seconds=float(postFrame['pts_time'])) == ts2: | ||||
|             # Nothing to do ! | ||||
|             pass | ||||
|         # Creating MKV file that corresponds to current part between I-frames  | ||||
|         with open('part-%d.mkv' % partnum, 'w') as partmkv: | ||||
|             extractMKVPart(inputFile=mkv, outputFile=partmkv, begin=preIFrameTS, end=postIFrameTS) | ||||
|          | ||||
|             # Trouver l'estampille de la trame 'I' la plus proche (mais postérieure) au début de la portion. | ||||
|             # Trouver l'estampille de la trame 'I' la plus proche (mais antérieure) à la fin de la portion. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user