#!/usr/bin/env python3 # ffmpeg-album-normalise: Normalise music album-by-album using FFmpeg loudnorm # Copyright © 2019 Lee Yingtong Li (RunasSudo) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import argparse import json import os.path import subprocess import sys parser = argparse.ArgumentParser(description='Scan audio files for loudness') parser.add_argument('filename', nargs='+', help='Input files') parser.add_argument('--levels', '-l', default='levels.json', help='levels.json output file') args = parser.parse_args() levels = {} if os.path.exists(args.levels): with open(args.levels, 'r') as f: levels = json.load(f) for filename in args.filename: print(filename) if filename in levels: continue proc = subprocess.run(['ffmpeg', '-i', filename, '-filter:a', 'loudnorm=print_format=json', '-f', 'null', '-'], capture_output=True, encoding='utf-8') if proc.returncode != 0: print('FFmpeg error') sys.exit(1) data_str = proc.stderr[proc.stderr.index('{', proc.stderr.index('Parsed_loudnorm_0')):] data = json.loads(data_str) levels[filename] = data with open(args.levels, 'w') as f: json.dump(levels, f)