1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| import ffmpeg import os import re import json from pathlib import Path
def analyze_loudness(input_path): """使用ffmpeg-python分析音频响度参数""" try: stdout, stderr = ( ffmpeg .input(input_path) .audio.filter('loudnorm', print_format='json') .output('pipe:', format='null') .global_args('-loglevel', 'info') .run(capture_stdout=True, capture_stderr=True) ) output = stderr.decode() except ffmpeg.Error as e: output = e.stderr.decode() json_match = re.search(r'\{.*\}', output, re.DOTALL) if not json_match: raise ValueError("未找到响度分析数据")
try: return json.loads(json_match.group()) except json.JSONDecodeError: raise ValueError("响度数据解析失败")
def normalize_video(input_path, output_path, target_lufs=-19): """执行标准化处理""" loudness_data = analyze_loudness(input_path)
input_stream = ffmpeg.input(input_path) audio_stream = input_stream.audio.filter( 'loudnorm', linear='true', I=target_lufs, measured_I=loudness_data['input_i'], measured_LRA=loudness_data['input_lra'], measured_tp=loudness_data['input_tp'], measured_thresh=loudness_data['input_thresh'], offset=loudness_data['target_offset'], print_format='summary' )
output = ffmpeg.output( input_stream.video, audio_stream, output_path, vcodec='copy', acodec='aac', audio_bitrate='192k', ar='48000', y='-y' )
try: output.run() except ffmpeg.Error as e: raise RuntimeError(f"处理失败: {e.stderr.decode()}")
def batch_normalize(): """批量处理当前目录下的视频文件""" video_exts = ['.mp4', '.mkv', '.mov', '.avi', '.flv'] current_dir = Path.cwd()
for file in current_dir.iterdir(): if file.suffix.lower() in video_exts and '_normalized' not in file.stem: output_name = f"{file.stem}_normalized{file.suffix}" output_path = file.with_name(output_name)
print(f"正在处理: {file.name}") try: normalize_video(str(file), str(output_path)) print(f"完成: {output_name}") except Exception: print(f"处理 {file.name} 失败: {str(Exception)}") if output_path.exists(): output_path.unlink()
if __name__ == "__main__": try: ffmpeg.probe('') except ffmpeg.Error: print("错误: 请先安装ffmpeg并添加到系统路径") exit(1)
batch_normalize()
|