tools

various tools I have been using throughout the years
Log | Files | Refs | README | LICENSE

lazymaster.py (1886B)


      1 #!/usr/bin/env python3
      2 import subprocess
      3 import sys
      4 import json
      5 from typing import cast
      6 
      7 
      8 def main():
      9     if len(sys.argv) < 2:
     10         print("lazymaster input.wav [output.wav]")
     11         sys.exit(1)
     12 
     13     input_file = sys.argv[1]
     14 
     15     # Measure loudness
     16     cmd_measure = [
     17         "ffmpeg",
     18         "-i",
     19         input_file,
     20         "-af",
     21         "loudnorm=I=-13:TP=-1:LRA=8:print_format=json",
     22         "-f",
     23         "null",
     24         "-",
     25     ]
     26 
     27     result = subprocess.run(cmd_measure, capture_output=True, text=True)
     28 
     29     # Parse output values
     30     try:
     31         stderr_output = result.stderr
     32         json_start = stderr_output.find("{")
     33         json_end = stderr_output.rfind("}") + 1
     34         if json_start == -1 or json_end == -1:
     35             raise ValueError("json output is missing")
     36 
     37         stats = cast(dict[str, str], json.loads(stderr_output[json_start:json_end]))
     38 
     39         measured_i = stats["input_i"]
     40         measured_tp = stats["input_tp"]
     41         measured_lra = stats["input_lra"]
     42         measured_thresh = stats["input_thresh"]
     43         offset = stats["target_offset"]
     44     except (ValueError, json.JSONDecodeError, KeyError) as e:
     45         print(f"error parsing loudness stats from ffmpeg output {e}")
     46         sys.exit(1)
     47 
     48     print(
     49         f"I={measured_i}, TP={measured_tp}, LRA={measured_lra}, Thresh={measured_thresh}, Offset={offset}"
     50     )
     51 
     52     # Normalize loudness
     53     if len(sys.argv) > 2:
     54         output_file = sys.argv[2]
     55         cmd_normalize = [
     56             "ffmpeg",
     57             "-i",
     58             input_file,
     59             "-af",
     60             f"loudnorm=I=-13:TP=-1:LRA=8:measured_I={measured_i}:measured_LRA={measured_lra}:measured_TP={measured_tp}:measured_thresh={measured_thresh}:offset={offset}:linear=true",
     61             "-y",
     62             output_file,
     63         ]
     64 
     65         _ = subprocess.run(cmd_normalize, check=True)
     66 
     67 
     68 if __name__ == "__main__":
     69     main()