# 音频文件LUFS响度归一化工具 **Repository Path**: lswjx/SetLufs ## Basic Information - **Project Name**: 音频文件LUFS响度归一化工具 - **Description**: 一个基于 WPF + FFmpeg 的音频响度归一化工具,支持批量扫描和将音频文件调整到统一的 LUFS 响度标准。 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: https://gitee.com/lswjx/SetLufs - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-06 - **Last Updated**: 2026-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: 音量, LUFS, 音量调整, 音乐, 音乐LUFS ## README # LUFS 响度归一化工具 SetLufs 是一款专业的音频响度归一化工具,基于 FFmpeg 的 loudnorm 滤镜实现精确的响度测量和调整,帮助您将音频文件统一到目标 LUFS 响度标准。 ### 主要功能 - 响度归一化:批量扫描和处理音频文件,支持 -23 至 -8 LUFS 范围的目标响度设置 - 多格式支持:支持 MP3、FLAC、WAV、DTS、APE 等 20+ 种音频格式 - 文件修复:自动检测并修复损坏的音频文件(MediaPlayer + FFmpeg 双重验证) - 格式转换:支持转换为 FLAC 无损格式或 WAV 无压缩格式 - 封面管理:查看、搜索、获取、浏览和嵌入音乐封面图片,支持批量扫描封面状态 - 音频播放:内置播放器,支持常见格式直接播放,特殊格式自动转码 - 多语言支持:中英文界面一键切换,文件元数据标签亦本地化显示 - 主题切换:支持亮色、暗色和跟随系统三种主题模式(基于 .NET 10 Fluent 主题) ### 技术特点 - 采用 FFmpeg loudnorm 两遍模式,实现高精度响度调整 - 支持 True Peak 限制,防止音频削波 - 根据文件大小自动优化并行处理线程数 - 全程异步处理,UI 流畅无卡顿 - 支持 DTS/APE 等特殊格式自动转换为 FLAC ## 功能特性 - **批量处理**:支持添加文件或整个目录,手动点击扫描开始测量 - **多格式支持**:MP3、FLAC、WAV、AAC、M4A、OGG、OPUS、WMA、AIFF、AU、AC3、DTS、EAC3、MKA、MP2、MPC、TTA、WV、MLP、THD、APE 等 20+ 种音频格式 - **响度扫描**:使用 FFmpeg `loudnorm` 滤镜测量当前响度和真峰值 - **自定义目标响度**:支持 -23 到 -8 LUFS 之间任意值,预置常用流媒体标准 - **自定义限制峰值**:支持 -2.0 到 -0.5 dBFS 之间任意值 - **三种输出模式**: - 输出到子目录(`_normalized`) - 覆盖原文件(带不可恢复提示,选否自动回退到子目录模式) - 输出到指定目录(可自定义输出路径,设置自动保存) - **音频播放**:支持直接播放常见格式(MP3/FLAC/WAV/AAC/M4A/OGG/WMA),DTS 等格式通过 FFmpeg 转码后播放 - **自动优化**:根据文件平均大小自动调整线程数和并发数 - **错误诊断**:处理失败时在状态列显示具体错误信息 - **特殊格式处理**:DTS、APE 文件自动转换为 FLAC 格式(无损压缩,音质相同)并提示用户 - **文件修复**:双重验证(MediaPlayer + FFmpeg 全量解码)检测损坏文件,修复流程为先尝试同格式重编码、失败再走 WAV 中间文件的两步修复法 - **格式转换**:支持批量转换为 FLAC 或 WAV 格式,保持原始采样率、采样大小和声道数 - **封面管理**:支持查看、搜索、获取、浏览和嵌入封面图片;DataGrid 封面列显示「有封面」/「无」状态;可右键「扫描封面」批量刷新封面状态;自动限制封面大小为 1200x1200 像素防止文件损坏 - **元数据保留**:所有处理操作(归一化、转换、修复)均通过 `-map_metadata` 和显式封面流映射保留原文件元数据 - **FFmpeg 自定义路径**:可手动指定 FFmpeg 可执行文件位置 - **多语言支持**:中英文界面一键切换,所有 UI 元素(含工具栏、状态栏、DataGrid 列头、右键菜单、元数据标签)实时更新 - **现代 UI**:基于 .NET 10 Fluent 主题(Mica 背景),进度条 + 文件数显示、右键菜单 - **三种主题模式**:亮色 / 暗色 / 跟随系统,支持实时切换 - **自定义对话框**:内置主题适配的消息对话框,替代系统 MessageBox - **软件设置窗口**:集中管理自动扫描、子目录扫描、语言切换、主题切换、输出方式、FFmpeg 路径等设置 - **处理前确认**:开始处理前弹出对话框,显示文件数量和输出方式,确认后再执行 - **帮助文档**:内置 HTML 帮助文档,点击工具栏「帮助」按钮用默认浏览器打开 ## 界面布局 主窗口分为四个区域: - **顶部工具栏**(WrapPanel 自动换行):添加文件 / 添加目录 / 删除选中 / 清空列表 | 扫描全部 / 开始处理 / 取消 | 目标响度 / 限制峰值 / 应用到全部 | 设置 / 帮助 / 关于 - **中部主区域**:左侧 DataGrid 文件列表(封面 / 文件名 / 格式 / 文件大小 / 当前响度 / 当前峰值 / 目标响度 / 限制峰值 / 状态,支持列排序),右侧封面预览面板(当前封面 + API 获取的封面 + 获取/浏览/应用按钮 + ← 切换 → + 文件元信息) - **底部播放器**:上一首 / 播放暂停 / 停止 / 下一首 + 进度条 + 音量 - **状态栏**:左侧 ℹ️ 图标 + 状态消息,右侧进度条 + 文件数(处理时显示)+ 流媒体响度提示 > 语言切换、输出模式、FFmpeg 状态等设置已迁移至「设置」窗口集中管理。 > 主题基于 .NET 10 官方 `PresentationFramework.Fluent`,窗口无 Background 时自动启用 Mica 背景。 ## 使用说明 ### 1. 准备 FFmpeg 程序需要 FFmpeg 才能运行。首次启动时,如果未找到 `ffmpeg.exe`,设置窗口的 FFmpeg 状态会显示"❌ FFmpeg 未找到"。 **方式一**:将 `ffmpeg.exe` 放在程序运行目录(通常是 `SetLufs.exe` 同级目录) **方式二**:打开「⚙️ 设置」→ FFmpeg 分组 → 点击"浏览..."按钮,手动选择 `ffmpeg.exe` 的路径 **方式三**:点击"下载"按钮,访问 [FFmpeg 官方下载页面](https://ffmpeg.org/download.html) ### 2. 添加文件 - 点击"添加文件"选择一个或多个音频文件 - 或点击"添加目录"批量导入整个文件夹(包含子目录) - 添加后文件状态为"待扫描",需手动点击扫描 - 扫描文件时会同时通过 ffprobe 检测每个文件的 `HasCover` 元数据,封面列显示「有封面」/「无」 ### 3. 扫描响度 - 点击"扫描全部":批量测量所有文件的当前响度和真峰值 - 或右键选中多个文件,选择"刷新选中" - 或右键点击单个文件,选择"刷新选中" ### 4. 设置目标值 - **目标响度 (LUFS)**:推荐 -14 LUFS(Spotify / YouTube 标准) - **限制峰值 (dBFS)**:推荐 -1.0 dBTP(防止削波) - 点击"应用到全部"可将当前设置应用到所有文件 - 也可以在 DataGrid 中单独为每行设置 - 点击下拉框后的 "?" 按钮可查看详细说明 ### 5. 软件设置 点击工具栏「⚙️ 设置」按钮打开设置窗口: - **通用设置**: - 添加文件或目录时自动分析响度(默认关闭) - 添加目录时扫描子目录(默认开启) - 界面语言切换(中文/English) - 主题模式切换(亮色/暗色/跟随系统) - **输出设置**: - 输出方式:子目录 / 覆盖原文件 / 指定目录 - 自定义输出目录(仅指定目录模式可用) - **FFmpeg 设置**: - FFmpeg 状态显示(绿色=已找到,红色=未找到) - 下载按钮:打开 FFmpeg 官方下载页 - 浏览按钮:手动选择 ffmpeg.exe ### 6. 选择输出模式 在「设置」窗口中选择输出方式: - **输出到子目录**:在原文件所在目录创建 `_normalized` 子目录,输出文件放入其中 - **覆盖原文件**:直接修改原始音频文件(不可恢复,处理前有确认提示) - **输出到指定目录**:选择自定义文件夹作为输出路径,设置会自动保存 ### 7. 开始处理 - 点击"开始处理"处理全部文件 - 或右键选中多个文件,选择"处理选中" - 开始前会弹出确认对话框,显示文件数量和输出方式 - 如果有 DTS 格式文件,会弹出提示告知将转换为 FLAC 格式 - 覆盖模式下 DTS 文件会有额外确认对话框,选"否"自动回退到子目录模式 ### 8. 播放音频 - 右键点击文件,选择"播放" - 常见格式(MP3/FLAC/WAV/AAC/M4A/OGG/WMA)直接播放 - DTS 等格式通过 FFmpeg 转码为临时 WAV 后播放(自动清理临时文件) - 文件名列有图标标识:🎵 可直接播放,⚠ 需转码播放 ### 9. 文件修复 - 右键选中文件 → 「修复选中」:修复选中的损坏文件 - 右键 → 「修复所有损坏文件」:自动检测列表中所有损坏文件并提示修复 - 损坏检测采用双重验证:MediaPlayer 原生播放测试 + FFmpeg 全量解码,任一失败即判定为损坏 - 修复流程:先尝试同格式重编码(RepairDirectAsync),失败再走 WAV 中间文件两步修复(RepairViaWavAsync) - 输出方式:覆盖模式使用系统临时目录中转(保留原文件时间戳),非覆盖模式输出到 `_repaired` 子目录并自动打开 - 检测结果缓存至文件列表变更,避免重复检测 ### 10. 格式转换 - 右键选中文件 → 「转为 FLAC」或「转为 WAV」 - FLAC 输出到 `_flac` 子目录,WAV 输出到 `_wav` 子目录 - 自动通过 ffprobe 检测并保持原始采样格式(`-sample_fmt`)、采样率、声道数 - 源文件已是目标格式时提示并跳过 ### 11. 封面管理 - **查看封面**:选中文件后右侧面板上方显示当前封面 - **扫描封面**:右键 → 「扫描封面」可批量刷新列表中所有文件的「有封面」/「无」状态(仅检测,不扫描响度,速度快) - **获取封面**:右侧「获取」按钮或右键 → 「获取」,调用网易云音乐 API 搜索封面(需网络) - **浏览封面**:点击「浏览」可从本地选择图片作为封面 - **切换封面**:搜索到多个结果时可用 ← / → 按钮切换 - **应用封面**:点击「应用」将选中封面嵌入音频文件 - 支持嵌入封面的格式:MP3、MP2、M4A、AAC、FLAC、OGG、MKA - DTS、WAV 等格式不支持嵌入封面,尝试时会提示 - 封面图片自动限制为 1200x1200 像素,超过会等比例缩放,防止文件损坏 ### 12. 语言切换 - 在「设置」窗口中选择"中文"或"English" - 切换后所有界面元素实时更新,包括文件信息面板的元数据标签(歌手名/专辑名/曲目名) ### 13. 查看帮助 - 点击工具栏「❓ 帮助」按钮 - 使用系统默认浏览器打开 HTML 帮助文档 - 包含完整的功能说明、操作指南和常见问题解答 ## 技术栈 - .NET 10 / WPF(PresentationFramework.Fluent 主题) - CommunityToolkit.Mvvm 8.4.2(MVVM + 源生成器) - FFmpeg(loudnorm 滤镜、ffprobe 元数据检测、封面嵌入) - Newtonsoft.Json 13.0.4 - LocalizationService(字典+属性模式,多语言支持) - 第三方 API:网易云音乐搜索 API、TheAudioDB 曲目查询 API ## 项目结构 ``` SetLufs/ ├── Models/ # 数据模型 │ ├── AudioFileItem.cs # 含 HasCover、IsPlayable、NeedsTranscode 等属性 │ ├── LoudnessMeasurement.cs │ ├── OutputMode.cs │ ├── AppSettings.cs # 应用设置持久化(settings.json) │ ├── ThemeMode.cs # 主题模式枚举(Light/Dark/System) │ └── ThemeOptionItem.cs # 主题选项项(解决语言切换时选中状态丢失) ├── Services/ # 服务层 │ ├── FfmpegService.cs # 测量/归一化/转码/修复/转换/封面检测与嵌入/元数据提取 │ ├── LocalizationService.cs # 多语言服务(字典+属性模式,单例) │ ├── AudioPlayerService.cs # MediaPlayer 封装 + 损坏检测 │ ├── PlaybackFormatService.cs │ ├── MusicInfoApiService.cs # 网易云音乐专辑封面搜索 API │ └── AudioDbService.cs # TheAudioDB 曲目信息查询 API ├── ViewModels/ # MVVM ViewModel │ └── MainViewModel.cs ├── Views/ # WPF 视图 │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── AboutWindow.xaml │ ├── AboutWindow.xaml.cs │ ├── SettingsWindow.xaml │ ├── SettingsWindow.xaml.cs │ ├── MessageDialog.xaml │ └── MessageDialog.xaml.cs ├── Resources/ # 样式和资源 │ ├── Styles/ │ │ └── Shared.xaml # Fluent 主题的薄包装样式 + 6 个值转换器 │ ├── app.ico # 程序图标 │ └── help.html # 帮助文档(HTML) ├── App.xaml # 应用程序资源定义 ├── App.xaml.cs # Application 子类(Fluent 主题加载、主题/语言恢复) ├── SetLufs.csproj # 项目配置文件(net10.0-windows, NoWarn WPF0001) ├── LICENSE # MIT 许可证 ├── README.md # 项目说明 └── code-wiki.md # 代码文档 ``` ## 注意事项 ### 性能优化 - 程序根据文件平均大小自动调整线程数: - 小文件(<10MB):单线程,高并发 - 中等文件(10-50MB):2线程 - 大文件(50-200MB):4线程 - 超大文件(>200MB):8线程,单并发 - **音频处理无法使用 GPU 加速**(loudnorm 滤镜和音频编码器均为纯 CPU 实现) - DTS 等多声道高码率文件扫描速度较慢(loudnorm 需全量解码所有声道) ### 特殊格式处理 - DTS 和 APE(Monkey's Audio)格式文件处理后自动转换为 FLAC 格式(这些格式只有解码器没有编码器,无法回写原格式) - FLAC 为无损压缩,音质与原文件相同,体积约为 WAV 的 50-60% - 处理前会弹出提示告知用户 - 所有处理操作通过 ffprobe 检测原文件 `sample_fmt`,无损格式显式指定 `-sample_fmt` 保持原始采样格式 - 封面流通过 `BuildMapAndCoverArgs` 按格式类型映射(WAV/AU 用 `-map 0:a`,M4A/AAC 用 `-map 0`,MP3/MP2 用 `-map 0 -disposition:v attached_pic -metadata:s:v comment="Cover (front)" -id3v2_version 3`,其他格式用 `-map 0 -disposition:v attached_pic`) ### 右键菜单顺序 文件列表右键菜单从上到下依次为: 1. 播放 2. 刷新选中 3. 处理选中 4. 转为 FLAC 5. 转为 WAV 6. 扫描封面(批量刷新封面状态) 7. 获取(调用网易云 API 搜索封面) 8. 修复选中 9. 修复所有损坏文件 10. 打开文件位置 ### 输出目录对应关系 | 操作 | 输出位置 | 自动打开目录 | |------|---------|------------| | 响度归一化(子目录模式) | `原目录/_normalized/` | 否 | | 响度归一化(覆盖模式) | 原位置(临时目录中转) | 否 | | 响度归一化(指定目录) | 自定义路径 | 否 | | 文件修复(非覆盖) | `原目录/_repaired/` | 是 | | 文件修复(覆盖) | 原位置(临时目录中转,保留时间戳) | 否 | | 转为 FLAC | `原目录/_flac/` | 是 | | 转为 WAV | `原目录/_wav/` | 是 | | 封面嵌入 | 原位置(直接修改) | 否 | ### 错误处理 - 处理失败时状态列显示具体错误信息(鼠标悬停查看完整内容) - 失败时自动清理空输出文件和空 `_normalized` 目录 - 覆盖模式使用临时目录方案,避免 FFmpeg 读写同文件失败 - 处理过程中禁止关闭窗口,防止文件写入中断导致损坏 ### 其他 - 浮点参数使用 InvariantCulture 格式化,避免中文系统下小数分隔符问题 - 处理前建议先扫描,未扫描的文件会提示"未扫描,跳过" - 语言设置自动保存到 `%LocalAppData%\SetLufs\lang.txt`,下次启动恢复 - 主题模式自动保存到 `%LocalAppData%\SetLufs\settings.json`,下次启动恢复 - FFmpeg 路径保存到 `%LocalAppData%\SetLufs\ffmpegpath.txt` - 自定义输出目录自动保存到 `%LocalAppData%\SetLufs\outputdir.txt` - 软件设置保存到 `%LocalAppData%\SetLufs\settings.json`,包括自动扫描、子目录扫描、主题模式等选项 - 处理前会弹出输出位置确认对话框,避免误操作 - DataGrid 按文件加载顺序显示(初始化时清空 SortDescriptions,避免按文件名排序) - 主题切换基于 .NET 10 官方 `Application.ThemeMode`,窗口不设置 Background 时自动启用 Mica 背景 - 封面嵌入使用 `-map 0:a -map 1:v -c:a copy -c:v copy` 参数,避免 `-map 0` 导致原有视频流干扰封面嵌入 ## 许可证 MIT License Copyright (c) 2026 weijx (lswjx@foxmail.com)