diff --git a/anime_audio_helper.py b/anime_audio_helper.py index 66d24b4..e6115e9 100644 --- a/anime_audio_helper.py +++ b/anime_audio_helper.py @@ -21,7 +21,7 @@ REMUX_CODECS = {"aac", "opus"} # Using a set for efficient lookups SVT_AV1_PARAMS = { "speed": "slower", # "slower", "slow", "medium", "fast", "faster" - "quality": "medium", # "higher", "high", "medium", "low", "lower" + "quality": "medium", # "lowest", "low", # "higher", "high", "medium", "low", "lower" "film-grain": 6, "color-primaries": 1, "transfer-characteristics": 1, @@ -96,28 +96,6 @@ def convert_audio_track(index, ch, lang, audio_temp_dir, source_file, should_dow ]) return final_opus -def run_ffmpeg_and_get_framecount(cmd): - import sys - import re - frame_count = None - last_line = "" - # Start ffmpeg process - with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as proc: - # Read stderr line by line - for line in proc.stderr: - sys.stdout.write(line) - sys.stdout.flush() - last_line = line - match = re.search(r"frame=\s*(\d+)", line) - if match: - frame_count = int(match.group(1)) - proc.wait() - if proc.returncode != 0: - raise RuntimeError(f"ffmpeg exited with code {proc.returncode}") - if frame_count is None: - raise RuntimeError("Could not determine frame count from ffmpeg output.") - return frame_count - def convert_video(source_file_base, source_file_full, is_vfr, target_cfr_fps_for_handbrake, autocrop_filter=None): print(" --- Starting Video Processing ---") scene_file = Path(f"{source_file_base}.txt") # Not used anymore, but kept for compatibility @@ -178,12 +156,12 @@ def convert_video(source_file_base, source_file_full, is_vfr, target_cfr_fps_for if autocrop_filter: ffmpeg_args += ["-vf", autocrop_filter] ffmpeg_args += video_codec_args + [str(ut_video_file)] - frame_count = run_ffmpeg_and_get_framecount(ffmpeg_args) + run_cmd(ffmpeg_args) ut_video_full_path = os.path.abspath(ut_video_file) # --- SVT-AV1 ENCODING (ffmpeg pipe to SvtAv1EncApp) --- print(" - Starting AV1 encode with ffmpeg -> SvtAv1EncApp pipe (this will take a long time)...") - # Probe UTVideo file for width, height, and frame count + # Probe UTVideo file for width, height (ffprobe) and frame count (mediainfo, fallback to ffprobe) ffprobe_dim_cmd = [ "ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height", "-of", "json", ut_video_full_path @@ -193,14 +171,27 @@ def convert_video(source_file_base, source_file_full, is_vfr, target_cfr_fps_for width = ffprobe_dim['streams'][0]['width'] height = ffprobe_dim['streams'][0]['height'] - ffprobe_framecount_cmd = [ - "ffprobe", "-v", "error", "-select_streams", "v:0", - "-count_frames", "-show_entries", "stream=nb_read_frames", - "-of", "json", ut_video_full_path - ] - ffprobe_framecount_json = run_cmd(ffprobe_framecount_cmd, capture_output=True) - ffprobe_framecount = json.loads(ffprobe_framecount_json) - frame_count = int(ffprobe_framecount['streams'][0].get('nb_read_frames', 0)) + # Try to get frame count from mediainfo (faster) + mediainfo_json = run_cmd([ + "mediainfo", "--Output=JSON", "-f", ut_video_full_path + ], capture_output=True) + media_info = json.loads(mediainfo_json) + frame_count = None + for track in media_info.get("media", {}).get("track", []): + if track.get("@type") == "Video": + frame_count = int(track.get("FrameCount", 0)) + break + + # Fallback to ffprobe if mediainfo fails + if not frame_count: + ffprobe_framecount_cmd = [ + "ffprobe", "-v", "error", "-select_streams", "v:0", + "-count_frames", "-show_entries", "stream=nb_read_frames", + "-of", "json", ut_video_full_path + ] + ffprobe_framecount_json = run_cmd(ffprobe_framecount_cmd, capture_output=True) + ffprobe_framecount = json.loads(ffprobe_framecount_json) + frame_count = int(ffprobe_framecount['streams'][0].get('nb_read_frames', 0)) svtav1_param_list = [ "--input-depth", "10",