def get_frames(self): """ Get total frame count of input file, returning total_frames from project if already exists """ # TODO: Unify get frames with vs pipe cache generation if self.frames > 0: return self.frames if self.chunk_method in ("vs_ffms2", "vs_lsmash"): vs = ( self.input if self.is_vs else create_vs_file(self.temp, self.input, self.chunk_method) ) fr = frame_probe_vspipe(vs) if fr > 0: self.frames = fr return fr total = frame_probe_fast(self.input, self.is_vs) self.frames = total return self.frames
def aom_keyframes(video_path: Path, stat_file, min_scene_len, ffmpeg_pipe, video_params, is_vs, quiet): """[Get frame numbers for splits from aomenc 1 pass stat file] """ log(f'Started aom_keyframes scenedetection\nParams: {video_params}\n') total = frame_probe_fast(video_path, is_vs) f, e = compose_aomsplit_first_pass_command(video_path, stat_file, ffmpeg_pipe, video_params, is_vs) tqdm_bar = None if (not quiet) and (not (tqdm is None)): tqdm_bar = tqdm(total=total, initial=0, dynamic_ncols=True, unit="fr", leave=True, smoothing=0.2) ffmpeg_pipe = subprocess.Popen(f, stdout=PIPE, stderr=STDOUT) pipe = subprocess.Popen(e, stdin=ffmpeg_pipe.stdout, stdout=PIPE, stderr=STDOUT, universal_newlines=True) encoder_history = deque(maxlen=20) frame = 0 while True: line = pipe.stdout.readline() if len(line) == 0 and pipe.poll() is not None: break line = line.strip() if line: encoder_history.append(line) if quiet or (tqdm is None): continue match = re.search(r"frame.*?/([^ ]+?) ", line) if match: new = int(match.group(1)) if new > frame: tqdm_bar.update(new - frame) frame = new if pipe.returncode != 0 and pipe.returncode != -2: # -2 is Ctrl+C for aom enc_hist = '\n'.join(encoder_history) er = f"\nAom first pass encountered an error: {pipe.returncode}\n{enc_hist}" log(er) print(er) if not stat_file.exists(): terminate() else: # aom crashed, but created keyframes.log, so we will try to continue print("WARNING: Aom first pass crashed, but created a first pass file. Keyframe splitting may not be accurate.") # aom kf-min-dist defaults to 0, but hardcoded to 3 in pass2_strategy.c test_candidate_kf. 0 matches default aom behavior # https://aomedia.googlesource.com/aom/+/8ac928be918de0d502b7b492708d57ad4d817676/av1/av1_cx_iface.c#2816 # https://aomedia.googlesource.com/aom/+/ce97de2724d7ffdfdbe986a14d49366936187298/av1/encoder/pass2_strategy.c#1907 min_scene_len = 0 if min_scene_len is None else min_scene_len keyframes = find_aom_keyframes(stat_file, min_scene_len) return keyframes
def get_frames(self): """ Get total frame count of input file, returning total_frames from project if already exists """ if self.frames > 0: return self.frames else: total = frame_probe_fast(self.input, self.is_vs) self.frames = total return self.frames