def _iterate_audio_frames_and_audio_gaps(audio_parts): if audio_parts is None: return last_part_idx = 0 last_part_last_frame = None for part_idx, audio_part in enumerate(audio_parts): frames = container_decode(audio_part.container, audio=0) frames = iter_catch(frames, av.AVError) for frame, timestamp in zip(frames, audio_part.timestamps): if frame is None: continue # ignore audio decoding errors frame.pts = None audio_frame = _AudioPacketIterator._AudioFrame( raw_frame=frame, start_time=timestamp ) if part_idx != last_part_idx: audio_gap = _AudioPacketIterator._AudioGap( start_time=last_part_last_frame.end_time, end_time=audio_frame.start_time, ) yield audio_gap yield audio_frame last_part_idx = part_idx last_part_last_frame = audio_frame
def load_container(self): try: cont = self._open_container() # Three failure scenarios: # 1. Broken video -> AVError # 2. decode() does not yield anything # 3. decode() yields None first_frame = next(container_decode(cont, video=0), None) if first_frame is None: raise InvalidContainerError("Container does not contain frames") except av.AVError as averr: raise InvalidContainerError from averr else: cont.seek(0) return cont
def get_frame_iterator(self): frames = container_decode(self.container, self.video_stream) frames = iter_catch(frames, av.AVError) for frame in frames: if frame: yield frame