11 KiB
P1 元数据解析与校验开发落地说明
1. 阶段定位
P1 阶段聚焦“元数据解析与校验”核心能力落地,并同步补齐目录扫描、一级去重、二级疑似去重、断点续传、已归档跳过等与验收直接相关的基础处理流程。
该阶段的核心目标是:系统能够读取音频文件元数据、生成原始快照、执行一票否决制校验,并用测试证明关键规则与真实文件读取能力已经落地。
2. 阶段目标
- 集成 Jaudiotagger,支持主流音频格式元数据读取
- 集成 juniversalchardet,完成编码检测与乱码修复尝试
- 实现
MetadataReaderService,读取标签、封面、编码并生成原始快照 - 实现
MetadataValidatorService,执行核心字段一票否决校验与清洗规则 - 建立
t_metadata_snapshot快照存储能力 - 为目录扫描、去重、断点续传提供落地实现与验收测试
- 使测试覆盖率达到 80% 以上
3. 技术落地概览
3.1 依赖集成
P1 阶段在 music-metadata-system/pom.xml 中新增:
net.jthink:jaudiotagger:2.2.5com.github.albfernandez:juniversalchardet:2.4.0org.jacoco:jacoco-maven-plugin:0.8.12
说明:原始需求写的是 Jaudiotagger 2.2.7,但实际 Maven 可解析并完成落地验证的版本为 2.2.5。当前功能已覆盖 MP3/FLAC/M4A/OGG/WAV 的读取需求,故以可稳定构建的版本为准。
3.2 领域模型与接口
新增元数据领域对象:
music-metadata-system/src/main/java/com/music/metadata/domain/metadata/AudioMetadata.javamusic-metadata-system/src/main/java/com/music/metadata/domain/metadata/CoverMetadata.javamusic-metadata-system/src/main/java/com/music/metadata/domain/metadata/MetadataValidationResult.javamusic-metadata-system/src/main/java/com/music/metadata/domain/metadata/ValidationFailure.javamusic-metadata-system/src/main/java/com/music/metadata/domain/metadata/ValidationFailureType.java
新增核心服务接口:
music-metadata-system/src/main/java/com/music/metadata/service/MetadataReaderService.javamusic-metadata-system/src/main/java/com/music/metadata/service/MetadataValidatorService.javamusic-metadata-system/src/main/java/com/music/metadata/service/MetadataSnapshotService.java
3.3 读取层实现
读取相关实现由两层组成:
-
JaudiotaggerAudioTagExtractor- 负责调用 Jaudiotagger 读取底层标签与封面信息
- 读取核心字段:
title、artist、album_artist、album、track、year、genre、lyrics、disc、comment - 汇总全部可枚举标签字段到
fields - 针对真实 FLAC 文件上 artwork/特殊字段抛异常的情况做了“尽力而为”兼容处理,避免整个读取流程失败
-
MetadataReaderServiceImpl- 将提取结果组装成
AudioMetadata - 自动识别文件格式
- 检测原始编码并尝试对 GBK/GB18030 类乱码做修复
- 解析封面格式、尺寸、二进制数据
- 生成原始元数据 JSON 快照
- 将快照持久化到
t_metadata_snapshot
- 将提取结果组装成
关键文件:
music-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/AudioTagExtractor.javamusic-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/AudioTagExtractionResult.javamusic-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/JaudiotaggerAudioTagExtractor.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/MetadataReaderServiceImpl.java
3.4 一票否决校验实现
MetadataValidatorServiceImpl 实现了严格的一票否决制:
- 编码非 UTF-8 且修复失败,立即返回
ENCODING_ERROR - 核心字段按顺序校验:
titleartistalbum_artistalbumtrackcover
- 任一字段缺失、乱码或不合规,立即返回失败,不继续后续字段校验
已落地规则包括:
- 强制 UTF-8 编码门禁
track必须为序号/总曲目数格式,例如01/12- 封面必须存在,且格式为 JPG/PNG,分辨率不小于
300x300,比例必须1:1 - 清洗规则涵盖:
- 首尾空白与不可见字符处理
- 非法文件名字符替换
- 多歌手分隔符统一
- 英文字段大小写规范化
- 版本信息从
title向comment迁移
关键文件:
music-metadata-system/src/main/java/com/music/metadata/service/impl/MetadataValidatorServiceImpl.java
3.5 元数据快照存储
新增快照实体与持久化层:
music-metadata-system/src/main/java/com/music/metadata/infrastructure/entity/MetadataSnapshotEntity.javamusic-metadata-system/src/main/java/com/music/metadata/infrastructure/mapper/MetadataSnapshotMapper.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/MetadataSnapshotServiceImpl.java
数据库脚本新增:
t_metadata_snapshot
对应位置:
music-metadata-system/src/main/resources/schema.sql
4. 同阶段补充完成的扫描与去重能力
虽然本次文档主题是“元数据解析与校验”,但当前 P1 代码实际还同时落地了与目录扫描相关的验收能力:
- 目录递归扫描
- 一级哈希去重(
HASH_DUPLICATE) - 二级特征疑似重复(
LEVEL2_SUSPECT) - 扫描断点续传
- 已归档文件再次扫描时自动跳过
相关代码:
music-metadata-system/src/main/java/com/music/metadata/service/impl/DirectoryScanServiceImpl.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/ScanFileProcessorImpl.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/DeduplicationServiceImpl.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/Sha256FileHashServiceImpl.javamusic-metadata-system/src/main/java/com/music/metadata/service/impl/JaudiotaggerAudioDurationServiceImpl.java
数据库脚本同步新增:
t_duplicate_filet_scan_itemt_file_process.dedup_key
5. 测试策略
P1 阶段测试分为三层:
5.1 纯单元测试
用于验证 reader、validator 的规则与边界行为:
music-metadata-system/src/test/java/com/music/metadata/service/impl/MetadataReaderServiceImplTest.javamusic-metadata-system/src/test/java/com/music/metadata/service/impl/MetadataValidatorServiceImplTest.java
5.2 验收测试
用于直接对应本阶段验收标准:
music-metadata-system/src/test/java/com/music/metadata/service/impl/MetadataAcceptanceTest.java
覆盖内容:
- 能正确读取测试音频文件元数据
- 缺失
title返回MISSING_FIELD - GBK 中文标签修复成功或返回
ENCODING_ERROR - 无封面返回
COVER_INVALID
5.3 真实音频集成测试
为满足“真实数据验证”口径,额外新增:
music-metadata-system/src/test/java/com/music/metadata/service/impl/RealAudioMetadataIntegrationTest.java
该测试会:
- 从真实目录
/home/liujingjing/下载/解压后2中选取 FLAC 文件 - 复制到临时目录,避免污染原始音乐库
- 直接使用
JaudiotaggerAudioTagExtractor读取真实文件 - 校验
fileFormat、title、artist、album、snapshotJson、tagFields、封面二进制与尺寸
如果需要切换目录,也可通过环境变量 REAL_AUDIO_DIR 覆盖默认路径。
5.4 覆盖率补强测试
为满足覆盖率要求,补充了基础设施与低覆盖类测试:
music-metadata-system/src/test/java/com/music/metadata/service/impl/CoverageSupportTest.javamusic-metadata-system/src/test/java/com/music/metadata/service/impl/SimpleServiceImplCoverageTest.javamusic-metadata-system/src/test/java/com/music/metadata/service/impl/JaudiotaggerAudioDurationServiceImplTest.java
5.5 测试资源说明
当前仓库未直接提交真实音频二进制测试资源,而是采用两种方式:
- 单元测试中使用
byte[]与 mock extractor 快速构造边界场景 - 在文档中说明真实 fixtures 的构造方式
说明文件:
music-metadata-system/src/test/resources/audio-fixtures/README.md
6. 验收结果
6.1 P1 核心验收项
| 验收项 | 结果 | 说明 |
|---|---|---|
| 能正确读取测试音频文件的元数据 | 通过 | RealAudioMetadataIntegrationTest 直接读取真实 FLAC 文件通过 |
缺失 title 字段返回 MISSING_FIELD |
通过 | MetadataAcceptanceTest 已覆盖 |
GBK 编码中文标签修复失败返回 ENCODING_ERROR |
通过 | MetadataAcceptanceTest 已覆盖“修复或失败”路径 |
无封面文件返回 COVER_INVALID |
通过 | MetadataAcceptanceTest 已覆盖 |
| 单元测试覆盖率 ≥ 80% | 通过 | 当前 JaCoCo 行覆盖率为 88.60% |
6.2 目录扫描附加验收项
| 验收项 | 结果 | 说明 |
|---|---|---|
| 一级哈希去重 | 通过 | DirectoryScanP1AcceptanceTest 已覆盖 |
| 二级疑似重复识别 | 通过 | DirectoryScanP1AcceptanceTest 已覆盖 |
| 扫描中断后断点续传 | 通过 | DirectoryScanP1AcceptanceTest 已覆盖 1000 文件场景 |
| 已归档文件再次扫描时跳过 | 通过 | DirectoryScanP1AcceptanceTest 已覆盖 |
7. 验证命令
推荐使用以下命令复验:
cd music-metadata-system
mvn test
针对元数据与真实文件验证,也可执行:
mvn -q -Dtest=RealAudioMetadataIntegrationTest,MetadataAcceptanceTest,MetadataReaderServiceImplTest,MetadataValidatorServiceImplTest test
覆盖率报告输出位置:
music-metadata-system/target/site/jacoco/index.htmlmusic-metadata-system/target/site/jacoco/jacoco.csv
8. 偏差与说明
8.1 Jaudiotagger 版本偏差
需求中写明 2.2.7,但实际可解析并完成稳定构建、测试通过的版本为 2.2.5。当前以 2.2.5 落地,后续如必须升级,可再做版本可用性验证。
8.2 编码修复策略说明
编码检测与乱码修复采用 juniversalchardet + 启发式修复 组合策略。对于疑似 GBK/GB18030 的中文乱码,会尝试修复;修复失败时,严格返回 ENCODING_ERROR。
8.3 真实数据与严格校验的关系
真实音频集成测试当前验证的是“能读出来”,而不是“真实目录中的所有文件都能通过 validator”。这是因为真实库中的部分文件可能存在 album_artist 缺失、track 不为 01/12 等情况,属于数据质量问题,不代表读取能力失败。
9. 阶段结论
P1 阶段已经完成元数据读取、快照持久化、一票否决校验、编码检测与清洗规则的核心落地,并通过真实音频集成测试、验收测试和覆盖率报告证明当前能力可用。
在此基础上,项目已经具备继续进入后续归档、失败文件人工兜底、权威 API 补全等更高层业务能力开发的条件。