diff --git a/av1_opus_encoder.py b/av1_opus_encoder.py index 35a75ac..102d5f0 100644 --- a/av1_opus_encoder.py +++ b/av1_opus_encoder.py @@ -71,31 +71,14 @@ def convert_audio_track(index, ch, lang, audio_temp_dir, source_file, should_dow # First pass: Analyze the audio to get loudnorm stats # The stats are printed to stderr, so we must use subprocess.run directly to capture it. print(" - Pass 1: Analyzing...") - - cmd = [ - "ffmpeg", "-v", "error", "-stats", "-i", str(temp_extracted), - "-af", "loudnorm=I=-18:LRA=7:tp=-1:print_format=json", "-f", "null", "-" - ] - - # Use Popen to capture stderr in real-time and print it, while also buffering for JSON parsing. - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding='utf-8') - - # Read stderr and print progress updates. - stderr_output = "" - for line in iter(process.stderr.readline, ''): - stderr_output += line # Buffer the full output for parsing - # Write the line, clearing the rest of the line with an ANSI escape code, - # and end with a carriage return to reset the line position. - sys.stdout.write(line.strip() + '\x1B[K\r') - sys.stdout.flush() # Ensure it's written immediately - - process.wait() # Wait for the process to terminate - if process.returncode != 0: - raise subprocess.CalledProcessError(process.returncode, cmd, output=process.stdout.read(), stderr="".join(stderr_buffer)) + result = subprocess.run( + ["ffmpeg", "-v", "info", "-i", str(temp_extracted), "-af", "loudnorm=I=-18:LRA=7:tp=-1:print_format=json", "-f", "null", "-"], + capture_output=True, text=True, check=True) # Find the start of the JSON block in stderr and parse it. # This is more robust than slicing the last N lines. # We find the start and end of the JSON block to avoid parsing extra data. + stderr_output = result.stderr json_start_index = stderr_output.find('{') if json_start_index == -1: raise ValueError("Could not find start of JSON block in ffmpeg output for loudnorm analysis.") @@ -113,9 +96,8 @@ def convert_audio_track(index, ch, lang, audio_temp_dir, source_file, should_dow stats = json.loads(stderr_output[json_start_index:json_end_index]) - # Second pass: Apply the normalization. A final newline is needed to clear the progress line. - # A print() is needed to move to the next line after the progress bar. - print("\n - Pass 2: Applying normalization...") + # Second pass: Apply the normalization using the stats from the first pass + print(" - Pass 2: Applying normalization...") run_cmd([ "ffmpeg", "-v", "quiet", "-stats", "-y", "-i", str(temp_extracted), "-af", f"loudnorm=I=-18:LRA=7:tp=-1:measured_i={stats['input_i']}:measured_lra={stats['input_lra']}:measured_tp={stats['input_tp']}:measured_thresh={stats['input_thresh']}:offset={stats['target_offset']}",