# mp3_operation **Repository Path**: fengsheng06/mp3_operation ## Basic Information - **Project Name**: mp3_operation - **Description**: No description available - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-24 - **Last Updated**: 2026-04-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MP3 操作工具集 一套基于 FFmpeg 的 MP3 音频文件处理工具,包含合并、分割、裁剪和扫描功能,以及目录管理工具。 ## 功能概述 - **mp3_merger**: 批量合并 MP3 文件(支持子目录批量处理), mp3名字是上一级目录的名字 - **mp3_spliter**: 分割 MP3 文件为多个片段 - **mp3_trimmer**: 裁剪 MP3 文件指定时间段 - **mp3_scaner**: 扫描并显示 MP3 文件信息 - **mp3_duration**: 显示目录中所有 MP3 文件的时长信息 - **dir_renamer**: 批量重命名三级目录(不需要 FFmpeg) - 实例:`artists/周杰伦/七里香/` → `artists/周杰伦/周杰伦_七里香/` - **file_renamer**: 批量重命名目录中的 MP3 文件(不需要 FFmpeg) - 实例:`林俊杰/江南.mp3` → `林俊杰/林俊杰_江南.mp3` - **space_remover**: 递归地将文件名和目录名中的空格替换为下划线(不需要 FFmpeg) ## 编译环境要求 ### 系统要求 - Linux 操作系统 - CMake 3.10+ - C++17 编译器(GCC 7.0+ 或 Clang 5.0+) ### 依赖库 - FFmpeg 开发库(libavformat, libavcodec, libavutil) - pkg-config ### 安装依赖 **Ubuntu/Debian:** ```bash sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev pkg-config cmake build-essential ``` **CentOS/RHEL:** ```bash sudo yum install ffmpeg-devel pkgconfig cmake gcc-c++ ``` ## 编译步骤 ```bash # 1. 进入项目目录 cd mp3_operation # 2. 创建并进入 build 目录 mkdir build && cd build # 3. 运行 CMake 配置 cmake .. # 4. 编译 make -j$(nproc) # 5. 查看生成的可执行文件 ls -lh mp3_* ``` 编译成功后,会在 build 目录生成以下可执行文件: - `mp3_merger` (约 75KB) - `mp3_spliter` (约 110KB) - `mp3_trimmer` (约 31KB) - `mp3_scaner` (约 76KB) - `mp3_duration` (约 80KB) - `dir_renamer` (约 71KB) - `file_renamer` (约 72KB) - `space_remover` (约 102KB) ## 工具详细说明 ### 1. mp3_merger - MP3 批量合并工具 **功能:** 批量合并子目录中的 MP3 文件,每个子目录生成一个合并后的 MP3 文件。 **使用场景:** - 合并专辑:每个子目录是一个专辑,包含多个音轨 - 有声书处理:每个子目录是一本书的章节 - 播客整理:每个子目录是一个系列的多期节目 #### 命令格式 ```bash ./mp3_merger ``` #### 参数说明 - `input_directory`: 一级输入目录,包含多个子目录(二级目录) - `output_directory`: 输出目录,合并后的 MP3 文件保存位置 #### 工作流程 1. 扫描 `input_directory` 下的所有二级子目录 2. 对每个子目录: - 查找其中的所有 MP3 文件 - 按文件名排序(确保顺序正确) - 合并成一个 MP3 文件 - 输出文件名 = 子目录名 + ".mp3" 3. 将合并后的文件保存到 `output_directory` 4. 显示处理进度和统计信息 #### 输入输出示例 **输入目录结构:** ``` /data/albums/ ├── 周杰伦-七里香/ │ ├── 01-我的地盘.mp3 │ ├── 02-七里香.mp3 │ ├── 03-借口.mp3 │ └── 04-外婆.mp3 ├── 周杰伦-叶惠美/ │ ├── 01-以父之名.mp3 │ ├── 02-懦夫.mp3 │ └── 03-晴天.mp3 └── 林俊杰-江南/ ├── track1.mp3 └── track2.mp3 ``` **执行命令:** ```bash ./mp3_merger /data/albums /data/merged ``` **输出结果:** ``` /data/merged/ ├── 周杰伦-七里香.mp3 (包含 4 首歌,按顺序合并) ├── 周杰伦-叶惠美.mp3 (包含 3 首歌,按顺序合并) └── 林俊杰-江南.mp3 (包含 2 首歌,按顺序合并) ``` #### 运行示例输出 ``` MP3 Batch Merger ================ Input directory: /data/albums Output directory: /data/merged Found 3 subdirectory(ies): [1] 周杰伦-七里香 [2] 周杰伦-叶惠美 [3] 林俊杰-江南 === Processing [1/3]: 周杰伦-七里香 === Found 4 MP3 file(s) in 周杰伦-七里香 Output: /data/merged/周杰伦-七里香.mp3 Merging 4 MP3 file(s)... [1/4] 01-我的地盘.mp3 [2/4] 02-七里香.mp3 [3/4] 03-借口.mp3 [4/4] 04-外婆.mp3 Success: Merged to /data/merged/周杰伦-七里香.mp3 === Processing [2/3]: 周杰伦-叶惠美 === Found 3 MP3 file(s) in 周杰伦-叶惠美 Output: /data/merged/周杰伦-叶惠美.mp3 Merging 3 MP3 file(s)... [1/3] 01-以父之名.mp3 [2/3] 02-懦夫.mp3 [3/3] 03-晴天.mp3 Success: Merged to /data/merged/周杰伦-叶惠美.mp3 === Processing [3/3]: 林俊杰-江南 === Found 2 MP3 file(s) in 林俊杰-江南 Output: /data/merged/林俊杰-江南.mp3 Merging 2 MP3 file(s)... [1/2] track1.mp3 [2/2] track2.mp3 Success: Merged to /data/merged/林俊杰-江南.mp3 === Summary === Successfully processed: 3 / 3 subdirectories All subdirectories processed successfully! ``` #### 注意事项 - 输出目录会自动创建(如果不存在) - MP3 文件按文件名字典序排序,建议使用 `01-`, `02-` 等前缀确保顺序 - 如果子目录中没有 MP3 文件,会跳过该目录并显示警告 - 所有 MP3 文件必须具有相同的编码格式,否则可能出现问题 - 支持中文目录名和文件名 #### 技术特性 - 使用 FFmpeg 进行无损合并(不重新编码) - 正确处理音频时间戳,确保连续播放 - 自动调整 PTS/DTS 时间戳 - 支持批量处理多个子目录 - 完整的错误处理和进度显示 --- ### 2. mp3_spliter - MP3 分割工具(三层结构) **功能:** 批量分割 MP3 文件,支持智能分割数量和三层目录结构。 **使用场景:** - 分割大型音频文件(有声书、播客、讲座等) - 将专辑中的多个长曲目批量分割 - 自动根据时长选择合适的分割数量 #### 命令格式 ```bash ./mp3_spliter [segment_count] ``` #### 参数说明 - `input_directory`: 一级输入目录,包含多个二级子目录 - `output_directory`: 输出根目录 - `segment_count`: (可选)分割片段数量 - **不指定**:自动判断(≤5小时分10份,>5小时分100份) - **指定**:使用指定的数量(如 20、50 等) #### 目录结构要求 **输入结构(三层):** ``` input_dir/ # 一级目录(输入根目录) ├── Album1/ # 二级目录(输入子目录) │ ├── track1.mp3 # 三级文件 │ └── track2.mp3 └── Audiobook1/ # 二级目录(输入子目录) └── chapter1.mp3 # 三级文件 ``` **输出结构(四层):** 对每个二级目录,创建一个同名的二级目录,其下包含两个子目录: ``` output_dir/ ├── Album1/ # 与输入子目录同名 │ ├── Album1_10part/ # 分割后的文件(10或100或指定数量) │ │ ├── track1_part001.mp3 │ │ ├── track1_part002.mp3 │ │ └── ... │ └── Album1_all_one/ # 原始文件拷贝 │ ├── track1.mp3 │ └── track2.mp3 └── Audiobook1/ # 与输入子目录同名 ├── Audiobook1_100part/ # 如果>5小时,自动分100份 │ └── ... └── Audiobook1_all_one/ └── chapter1.mp3 ``` #### 使用示例 **示例 1: 自动判断分割数量** ```bash ./mp3_spliter /music/albums /output/split ``` - 时长 ≤ 5小时:分割为 10 份 - 时长 > 5小时:分割为 100 份 **示例 2: 指定分割数量** ```bash ./mp3_spliter /music/albums /output/split 20 ``` - 所有文件统一分割为 20 份 **示例 3: 处理有声书** ```bash ./mp3_spliter /audiobooks/input /audiobooks/output ``` #### 运行示例输出 ``` ======================================== MP3 Splitter (3-Level Structure) ======================================== Input directory: /music/albums Output directory: /output/split Segment count: Auto (10 or 100 based on duration) ======================================== Found 2 subdirectory(ies): [1] Album1 [2] Audiobook1 ======================================== Processing subdirectory: Album1 Found 2 MP3 file(s) ======================================== Total duration: 4200.00 seconds (1.17 hours) Auto-determined segment count: 10 Split output: /output/split/Album1/Album1_10part Copy output: /output/split/Album1/Album1_all_one --- File 1/2: track1.mp3 --- Copied to: track1.mp3 Duration: 2100.00 seconds Splitting into 10 parts... Success: All 10 segments created --- File 2/2: track2.mp3 --- Copied to: track2.mp3 Duration: 2100.00 seconds Splitting into 10 parts... Success: All 10 segments created ======================================== Subdirectory summary for Album1: Files successfully split: 2 / 2 Files successfully copied: 2 / 2 ======================================== ======================================== Processing subdirectory: Audiobook1 Found 1 MP3 file(s) ======================================== Total duration: 21600.00 seconds (6.00 hours) Auto-determined segment count: 100 Split output: /output/split/Audiobook1/Audiobook1_100part Copy output: /output/split/Audiobook1/Audiobook1_all_one --- File 1/1: chapter1.mp3 --- Copied to: chapter1.mp3 Duration: 21600.00 seconds Splitting into 100 parts... Success: All 100 segments created ======================================== Subdirectory summary for Audiobook1: Files successfully split: 1 / 1 Files successfully copied: 1 / 1 ======================================== ======================================== Final Summary ======================================== Successfully processed: 2 / 2 subdirectories Output location: /output/split ======================================== ``` #### 分割规则 - **平均分割**:每段时长 = 总时长 / 分割数量 - **准确时长**:使用完整文件扫描获取准确的音频时长 - **智能判断**: - 计算子目录下所有 MP3 文件的总时长 - 总时长 ≤ 5小时 → 10 份 - 总时长 > 5小时 → 100 份 #### 输出文件命名 - 分割文件:`原文件名_part001.mp3`, `原文件名_part002.mp3`, ... - 拷贝文件:保持原文件名 #### 注意事项 - 要求三层目录结构(一级目录/二级目录/MP3文件) - 对每个二级目录独立处理 - 同时生成分割版本和原始拷贝 - 自动创建输出目录 - 支持批量处理多个子目录 - 使用准确的时长扫描,避免 bitrate 估算误差 #### 技术特性 - 使用 FFmpeg 进行无损分割 - 平均分割算法 - 准确的音频时长扫描(完整读取所有帧) - 自动时间戳调整 - 完整的错误处理 --- ### 3. mp3_trimmer - MP3 裁剪工具 **功能:** 从 MP3 文件中提取指定时间段。 #### 命令格式 ```bash ./mp3_trimmer ``` #### 参数说明 - `input_file`: 输入 MP3 文件 - `output_file`: 输出 MP3 文件 - `start_time_seconds`: 开始时间(秒) - `end_time_seconds`: 结束时间(秒) #### 使用示例 **示例 1: 裁剪 10 秒到 60 秒的片段** ```bash ./mp3_trimmer input.mp3 output.mp3 10 60 ``` **示例 2: 提取前 30 秒** ```bash ./mp3_trimmer song.mp3 intro.mp3 0 30 ``` **示例 3: 提取副歌部分(1分30秒到2分钟)** ```bash ./mp3_trimmer song.mp3 chorus.mp3 90 120 ``` #### 运行示例 ``` Trimming MP3 file... Input: input.mp3 Output: output.mp3 Time range: 10s - 60s Success: Trimmed file saved to output.mp3 ``` --- ### 4. mp3_scaner - MP3 扫描工具 **功能:** 扫描目录中的 MP3 文件,显示文件信息。 #### 命令格式 ```bash ./mp3_scaner <目录路径> ``` #### 使用示例 ```bash ./mp3_scaner /path/to/mp3/folder ``` --- ### 5. mp3_duration - MP3 时长显示工具(递归) **功能:** 递归显示目录树中所有 MP3 文件的时长信息,按目录分组统计。 **使用场景:** - 查看整个音乐库的总时长 - 统计多个专辑或有声书的时长 - 递归浏览所有子目录的 MP3 文件时长信息 #### 命令格式 ```bash ./mp3_duration ``` #### 参数说明 - `input_directory`: 包含 MP3 文件的根目录(支持递归处理) #### 使用示例 **示例 1: 查看音乐专辑时长** ```bash ./mp3_duration /music/albums/周杰伦-七里香 ``` **示例 2: 递归查看整个音乐库** ```bash ./mp3_duration /music/library ``` **示例 3: 查看有声书时长** ```bash ./mp3_duration /audiobooks ``` #### 运行示例输出 ``` Scanning directory recursively: /music/library Duration(m) Time File ======================================================================================= [.] --------------------------------------------------------------------------------------- 4.52 4m 31s album1.mp3 5.01 5m 1s album2.mp3 --------------------------------------------------------------------------------------- 9.53 9m 32s Subtotal (2 files) [Artist1/Album1] --------------------------------------------------------------------------------------- 4.78 4m 47s track1.mp3 4.35 4m 21s track2.mp3 3.92 3m 55s track3.mp3 --------------------------------------------------------------------------------------- 13.05 13m 3s Subtotal (3 files) [Artist1/Album2] --------------------------------------------------------------------------------------- 4.26 4m 16s song1.mp3 3.68 3m 41s song2.mp3 --------------------------------------------------------------------------------------- 7.94 7m 57s Subtotal (2 files) [Artist2/Best Hits] --------------------------------------------------------------------------------------- 4.15 4m 9s hit1.mp3 3.84 3m 50s hit2.mp3 4.42 4m 25s hit3.mp3 --------------------------------------------------------------------------------------- 12.41 12m 24s Subtotal (3 files) ======================================================================================= 42.93 42m 56s Grand Total (10 files in 4 directories) ``` #### 输出说明 - **Duration(m)**: 时长(分钟) - **Time**: 格式化的时长(时:分:秒) - **File**: 文件名 - **Subtotal**: 每个目录的小计 - **Grand Total**: 总计(所有文件和目录数) #### 特性 - **递归扫描**:自动处理所有子目录 - **按目录分组**:每个目录单独显示并统计 - **精确时长**:使用完整文件扫描获取准确时长 - **三级统计**:文件级、目录级、总计级 - 自动按路径和文件名排序显示 - 清晰的表格化输出 - 对于没有明确时长信息的文件,会完整扫描获取准确时长 #### 技术特性 - 使用 FFmpeg 获取准确时长 - 递归遍历目录树 - 使用 std::filesystem 进行目录操作 - 完整的帧扫描确保时长准确 - 自动过滤非 MP3 文件 --- ### 6. dir_renamer - 目录重命名工具 **功能:** 批量重命名三级目录,将三级目录名改为"二级目录名_三级目录名"的格式。 **使用场景:** - 整理音乐库目录结构,添加艺术家或专辑前缀 - 组织文件归档,为子目录添加分类前缀 - 批量重命名项目目录,添加父目录标识 **注意:** 此工具不需要 FFmpeg 库,可以独立编译使用。 #### 命令格式 ```bash ./dir_renamer ``` #### 参数说明 - `input_dir`: 一级目录路径 #### 重命名规则 假设有以下目录结构: ``` input_dir/ ├── parent1/ │ ├── child1/ │ └── child2/ └── parent2/ ├── subdir1/ └── subdir2/ ``` 重命名后变为: ``` input_dir/ ├── parent1/ │ ├── parent1_child1/ │ └── parent1_child2/ └── parent2/ ├── parent2_subdir1/ └── parent2_subdir2/ ``` #### 使用示例 **示例 1: 整理音乐库** ```bash ./dir_renamer /music/artists ``` 假设目录结构为: ``` /music/artists/ ├── 周杰伦/ │ ├── 七里香/ │ └── 叶惠美/ └── 林俊杰/ ├── 江南/ └── 学不会/ ``` 重命名后: ``` /music/artists/ ├── 周杰伦/ │ ├── 周杰伦_七里香/ │ └── 周杰伦_叶惠美/ └── 林俊杰/ ├── 林俊杰_江南/ └── 林俊杰_学不会/ ``` **示例 2: 整理项目归档** ```bash ./dir_renamer /projects/archive ``` #### 运行示例输出 ``` 扫描目录: "/music/artists" ======================================== 需要重命名的三级目录清单 (共 4 项): ======================================== [1] 二级目录: 周杰伦 旧名称: 七里香 新名称: 周杰伦_七里香 完整旧路径: "/music/artists/周杰伦/七里香" 完整新路径: "/music/artists/周杰伦/周杰伦_七里香" [2] 二级目录: 周杰伦 旧名称: 叶惠美 新名称: 周杰伦_叶惠美 完整旧路径: "/music/artists/周杰伦/叶惠美" 完整新路径: "/music/artists/周杰伦/周杰伦_叶惠美" [3] 二级目录: 林俊杰 旧名称: 江南 新名称: 林俊杰_江南 完整旧路径: "/music/artists/林俊杰/江南" 完整新路径: "/music/artists/林俊杰/林俊杰_江南" [4] 二级目录: 林俊杰 旧名称: 学不会 新名称: 林俊杰_学不会 完整旧路径: "/music/artists/林俊杰/学不会" 完整新路径: "/music/artists/林俊杰/林俊杰_学不会" ======================================== 按任意键继续重命名,或按 Ctrl+C 取消... 开始执行重命名操作... [1/4] 重命名: 七里香 -> 周杰伦_七里香 成功! [2/4] 重命名: 叶惠美 -> 周杰伦_叶惠美 成功! [3/4] 重命名: 江南 -> 林俊杰_江南 成功! [4/4] 重命名: 学不会 -> 林俊杰_学不会 成功! ======================================== 重命名完成! 成功: 4 项 失败: 0 项 ======================================== ``` #### 工作流程 1. **扫描目录** - 扫描一级目录下的所有二级和三级目录 2. **显示清单** - 列出需要修改的目录清单,包括: - 二级目录名 - 原三级目录名 - 新三级目录名 - 完整旧路径和新路径 3. **等待确认** - 按任意键继续,或按 Ctrl+C 取消 4. **执行重命名** - 执行重命名操作并显示进度和结果 #### 注意事项 - 先显示修改清单,等待用户确认后再执行 - 自动跳过已经符合命名规则的目录(名字已经是"父目录_子目录"格式) - 检测目标路径是否已存在,避免冲突 - 支持中文目录名 - 显示详细的成功/失败统计 - 只修改三级目录,不影响二级目录和文件 #### 技术特性 - 使用 C++17 std::filesystem 库 - 不依赖 FFmpeg,独立编译 - 完整的错误处理 - 安全的重命名操作(先检查后执行) --- ### 7. file_renamer - 文件重命名工具 **功能:** 批量重命名目录中的 MP3 文件,将文件名改为"目录名_文件名"的格式。 **使用场景:** - 为音乐文件添加艺术家或专辑前缀 - 整理文件时添加分类标识 - 避免不同目录中的同名文件冲突 **注意:** - 此工具不需要 FFmpeg 库,可以独立编译使用 - 只能处理不包含子目录的目录(即目录下只能有文件,不能有子目录) #### 命令格式 ```bash ./file_renamer ``` #### 参数说明 - `input_dir`: 包含 MP3 文件的目录路径(可以是相对路径或绝对路径) #### 重命名规则 程序会从输入路径中提取最后一级目录名作为前缀。 假设目录结构为: ``` /music/周杰伦/ ├── 七里香.mp3 ├── 晴天.mp3 └── 稻香.mp3 ``` 重命名后变为: ``` /music/周杰伦/ ├── 周杰伦_七里香.mp3 ├── 周杰伦_晴天.mp3 └── 周杰伦_稻香.mp3 ``` #### 使用示例 **示例 1: 使用相对路径** ```bash ./file_renamer 周杰伦 ``` **示例 2: 使用绝对路径** ```bash ./file_renamer /music/artists/林俊杰 ``` 假设目录中有:`江南.mp3` 和 `曹操.mp3` 重命名后: - `林俊杰_江南.mp3` - `林俊杰_曹操.mp3` #### 运行示例输出 ``` 检查目录: "/music/artists/林俊杰" 目录包含 2 个文件 提取的目录名: 林俊杰 ======================================== 目录名: 林俊杰 需要重命名的 MP3 文件清单 (共 2 项): ======================================== [1] 旧文件名: 江南.mp3 新文件名: 林俊杰_江南.mp3 [2] 旧文件名: 曹操.mp3 新文件名: 林俊杰_曹操.mp3 ======================================== 按任意键继续重命名,或按 Ctrl+C 取消... 开始执行重命名操作... [1/2] 重命名: 江南.mp3 -> 林俊杰_江南.mp3 成功! [2/2] 重命名: 曹操.mp3 -> 林俊杰_曹操.mp3 成功! ======================================== 重命名完成! 成功: 2 项 失败: 0 项 ======================================== ``` #### 工作流程 1. **检查目录** - 验证目录存在且不包含子目录 2. **提取目录名** - 从路径中提取最后一级目录名 3. **扫描文件** - 查找所有 MP3 文件 4. **显示清单** - 列出需要重命名的文件清单 5. **等待确认** - 按任意键继续,或按 Ctrl+C 取消 6. **执行重命名** - 执行重命名操作并显示结果 #### 注意事项 - **目录要求**:目录下只能包含文件,不能包含子目录 - 如果目录中有子目录,程序会报错并退出 - 这是为了避免意外修改复杂的目录结构 - **文件限制**:只处理 `.mp3` 扩展名的文件,其他文件不受影响 - **重复检查**:如果目标文件名已存在,会跳过该文件并报告错误 - **跳过已改名**:如果文件名已经是"目录名_文件名"格式,会自动跳过 - 支持中文目录名和文件名 - 显示详细的成功/失败统计 #### 错误处理示例 **情况 1: 目录包含子目录** ``` $ ./file_renamer /music/albums 错误: 目录下包含 3 个子目录 此工具只能处理不包含子目录的目录 ``` **情况 2: 目录为空** ``` $ ./file_renamer /empty/folder 错误: 目录下没有文件 ``` **情况 3: 目标文件已存在** ``` [1/3] 重命名: song.mp3 -> artist_song.mp3 错误: 目标文件已存在,跳过: /music/artist/artist_song.mp3 ``` #### 技术特性 - 使用 C++17 std::filesystem 库 - 不依赖 FFmpeg,独立编译 - 智能路径处理(支持相对路径和绝对路径) - 完整的错误处理和验证 - 安全的重命名操作(先检查后执行) #### 与 dir_renamer 的区别 | 工具 | 操作对象 | 使用场景 | |------|----------|----------| | **dir_renamer** | 重命名目录(三级目录) | 整理多层目录结构 | | **file_renamer** | 重命名文件 | 为单个目录中的文件添加前缀 | --- ### 8. space_remover - 空格替换工具 **功能:** 递归地将目录树中所有 MP3 文件和子目录名中的空格替换为下划线。 **使用场景:** - 处理从 Windows 或其他系统迁移的文件,统一命名规则 - 避免在命令行或脚本中处理包含空格的文件名 - 清理音乐库中的文件名和目录名 - 准备文件用于需要无空格路径的应用程序 **注意:** 此工具不需要 FFmpeg 库,可以独立编译使用。 #### 命令格式 ```bash ./space_remover ``` #### 参数说明 - `input_dir`: 要处理的根目录路径(支持递归处理所有子目录) #### 处理规则 - **MP3 文件**:所有 `.mp3` 文件名中的空格替换为 `_` - **目录**:所有子目录名中的空格替换为 `_` - **递归处理**:自动处理所有层级的子目录 - **智能排序**:先处理深层目录,再处理浅层目录(避免路径失效) #### 使用示例 **示例 1: 处理音乐库** ```bash ./space_remover /music/library ``` 假设目录结构为: ``` /music/library/ ├── Artist Name/ │ ├── Album Name/ │ │ ├── Song 1.mp3 │ │ └── Song 2.mp3 │ └── Another Track.mp3 └── Pop Music/ └── Hit Song.mp3 ``` 处理后变为: ``` /music/library/ ├── Artist_Name/ │ ├── Album_Name/ │ │ ├── Song_1.mp3 │ │ └── Song_2.mp3 │ └── Another_Track.mp3 └── Pop_Music/ └── Hit_Song.mp3 ``` **示例 2: 处理有声书目录** ```bash ./space_remover "/audiobooks/Harry Potter" ``` #### 运行示例输出 ``` 扫描目录: "/music/library" 正在递归扫描文件和目录... ======================================== 需要重命名的项目清单: MP3 文件: 4 个 目录: 3 个 总计: 7 项 ======================================== [1] [目录] 旧名称: Artist Name 新名称: Artist_Name 路径: "/music/library" [2] [目录] 旧名称: Album Name 新名称: Album_Name 路径: "/music/library/Artist Name" [3] [文件] 旧名称: Another Track.mp3 新名称: Another_Track.mp3 路径: "/music/library/Artist Name" [4] [文件] 旧名称: Song 1.mp3 新名称: Song_1.mp3 路径: "/music/library/Artist Name/Album Name" [5] [文件] 旧名称: Song 2.mp3 新名称: Song_2.mp3 路径: "/music/library/Artist Name/Album Name" [6] [目录] 旧名称: Pop Music 新名称: Pop_Music 路径: "/music/library" [7] [文件] 旧名称: Hit Song.mp3 新名称: Hit_Song.mp3 路径: "/music/library/Pop Music" ======================================== 按任意键继续重命名,或按 Ctrl+C 取消... 开始执行重命名操作... [1/7] [文件] Song 1.mp3 -> Song_1.mp3 成功! [2/7] [文件] Song 2.mp3 -> Song_2.mp3 成功! [3/7] [目录] Album Name -> Album_Name 成功! [4/7] [文件] Another Track.mp3 -> Another_Track.mp3 成功! [5/7] [目录] Artist Name -> Artist_Name 成功! [6/7] [文件] Hit Song.mp3 -> Hit_Song.mp3 成功! [7/7] [目录] Pop Music -> Pop_Music 成功! ======================================== 重命名完成! 成功: 7 项 失败: 0 项 ======================================== ``` #### 工作流程 1. **扫描目录** - 递归扫描所有子目录和 MP3 文件 2. **识别空格** - 找出所有名称中包含空格的项目 3. **显示清单** - 列出所有需要重命名的文件和目录 4. **等待确认** - 按任意键继续,或按 Ctrl+C 取消 5. **智能排序** - 按深度降序排序(先处理深层,后处理浅层) 6. **执行重命名** - 逐个重命名并显示进度 #### 注意事项 - **递归处理**:会处理所有层级的子目录,无深度限制 - **只处理 MP3**:只重命名 `.mp3` 文件,其他类型文件不受影响 - **目录也处理**:所有子目录名中的空格也会被替换 - **智能顺序**:先处理深层文件和目录,避免父目录重命名导致路径失效 - **跳过无空格**:名称中没有空格的项目会被自动跳过 - **冲突检查**:如果目标名称已存在,会跳过并报错 - 支持中文文件名和目录名 - 显示详细的成功/失败统计 #### 技术特性 - 使用 C++17 std::filesystem 库 - 不依赖 FFmpeg,独立编译 - 递归遍历目录树 - 按深度智能排序,保证重命名顺序正确 - 完整的错误处理 - 安全的重命名操作(先检查后执行) #### 实用提示 **命令行使用技巧:** ```bash # 如果路径包含空格,需要用引号括起来 ./space_remover "/path/with spaces/music" # 使用绝对路径 ./space_remover /home/user/music # 使用相对路径 ./space_remover ../music/albums ``` **批量处理多个目录:** ```bash #!/bin/bash # 处理多个音乐目录 for dir in "/music/Rock" "/music/Pop" "/music/Jazz"; do ./space_remover "$dir" done ``` --- ## 常见问题 ### Q1: 编译时出现 "undefined reference to mpg123_xxx" 错误 **A:** 这是因为系统缺少 libmpg123 库。某些 FFmpeg 版本依赖此库。 解决方案: ```bash # Ubuntu/Debian sudo apt-get install libmpg123-dev # CentOS/RHEL sudo yum install mpg123-devel ``` ### Q2: MP3 合并后播放不流畅或有杂音 **A:** 可能是因为源文件的编码格式不一致(如比特率、采样率不同)。 建议: - 确保所有源 MP3 文件使用相同的比特率(如 320kbps) - 确保所有源 MP3 文件使用相同的采样率(如 44100Hz) ### Q3: 文件名包含中文或特殊字符时出错 **A:** 确保系统 locale 设置正确: ```bash export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8 ``` ### Q4: 如何批量处理大量文件? **A:** 可以使用 shell 脚本配合这些工具。例如: ```bash #!/bin/bash # 批量处理多个目录 for album_dir in /music/albums/*/; do ./mp3_merger "$album_dir" /output/merged/ done ``` ### Q5: dir_renamer 会影响我的文件吗? **A:** 不会。dir_renamer 只重命名目录(文件夹),不会移动、修改或删除任何文件。所有文件都会保持在原来的位置,只是它们所在的目录名称会改变。 ### Q6: 如果我不小心用 dir_renamer 重命名错了怎么办? **A:** dir_renamer 有安全机制: 1. 执行前会显示完整的修改清单,需要按键确认 2. 如果需要撤销,可以手动重命名回去,或者再次运行 dir_renamer(已经改名的目录会被跳过) 如果需要批量还原,可以写一个简单的脚本: ```bash #!/bin/bash # 示例:将 parent_child 还原为 child for dir in /path/to/parent/parent_*/; do dirname=$(basename "$dir") newname="${dirname#parent_}" # 移除 parent_ 前缀 mv "$dir" "$(dirname "$dir")/$newname" done ``` ### Q7: mp3_spliter 的智能分割是怎么判断的? **A:** 智能分割基于目录下所有 MP3 文件的**总时长**: - 计算子目录下所有 MP3 文件的总时长 - 总时长 ≤ 5 小时:分割为 **10** 份 - 总时长 > 5 小时:分割为 **100** 份 如果想使用固定的分割数量,可以手动指定第三个参数: ```bash ./mp3_spliter /input /output 20 # 强制分割为 20 份 ``` ### Q8: mp3_spliter 和 mp3_duration 的时长准确吗? **A:** 非常准确!这两个工具都使用了完整的文件扫描方法: 1. 首先尝试从容器/流获取时长 2. 如果不准确,会读取整个文件的所有帧来计算准确时长 3. 避免了基于 bitrate 估算的误差 4. 自动降低日志级别,不会显示 "Estimating duration from bitrate" 警告 ### Q9: mp3_spliter 的输出目录结构是什么? **A:** 对每个二级子目录,创建一个同名的二级目录,其下包含两个子目录: ``` output_dir/ └── SubDir/ # 与输入子目录同名(新增层级) ├── SubDir_10part/ # 或 _100part,或 _20part(指定时) │ └── 分割后的文件 └── SubDir_all_one/ # 原始文件拷贝 └── 原始文件 ``` **四层结构的好处:** - 更清晰的目录组织,每个输入子目录对应一个输出子目录 - `_Npart` 目录:方便使用分割后的小文件 - `_all_one` 目录:保留原始文件作为备份 - 避免输出目录根目录下文件过多 --- ## 技术说明 ### 音频处理原理 - 使用 FFmpeg 库进行音频操作 - 直接操作音频流,不重新编码(无损) - 正确处理 PTS/DTS 时间戳,确保音频连续性 - 支持所有 FFmpeg 支持的 MP3 编码格式 ### 代码特性 - C++17 标准 - 使用 FFmpeg 4.0+ API(移除了所有已弃用的 API) - 完整的错误处理 - 内存安全(RAII 模式管理资源) - 清晰的代码结构和注释 ### 性能 - 快速处理:100MB MP3 文件合并约需 1-2 秒 - 低内存占用:流式处理,不需要将整个文件加载到内存 - 支持多核编译:`make -j$(nproc)` --- ## 版本历史 ### v1.2 (2026-02-05) - ✨ 新增 file_renamer 工具:批量重命名目录中的 MP3 文件,添加目录名前缀(不需要 FFmpeg) - ✨ 新增 space_remover 工具:递归地将文件名和目录名中的空格替换为下划线(不需要 FFmpeg) - 🔧 重写 mp3_spliter: - 支持三层输入目录结构(一级/二级/文件) - 四层输出目录结构(输出根/子目录/分割目录|原始目录/文件) - 智能分割数量(≤5小时分10份,>5小时分100份) - 支持手动指定分割数量(可选参数) - 为每个子目录创建独立的输出目录,包含两个子目录(_Npart 和 _all_one) - 改进时长获取:使用完整文件扫描确保准确性 - 🔧 改进 mp3_duration: - 支持递归遍历所有子目录 - 按目录分组显示统计信息 - 显示总计和子目录小计 - 📝 完善文档,更新所有工具的详细说明和使用示例 ### v1.1 (2026-02-05) - ✨ 新增 mp3_duration 工具:显示目录中所有 MP3 文件的时长信息 - ✨ 新增 dir_renamer 工具:批量重命名三级目录(不需要 FFmpeg) - 📝 完善文档,添加新工具的详细说明和使用示例 ### v1.0 (2025-02-05) - ✨ 完全重写 mp3_merger,支持批量处理子目录 - ✨ 改进所有工具的用户界面和错误提示 - 🐛 修复 FFmpeg 弃用 API 问题 - 🐛 修复时间戳处理问题 - 📝 完善文档和使用示例 - 🔧 添加 CMake 构建系统 --- ## 许可证 本项目使用 MIT 许可证。 --- ## 贡献 欢迎提交 Issue 和 Pull Request! --- ## 联系方式 如有问题或建议,请提交 Issue。