Files
music-metadata-system/docs/P1-元数据解析与校验-开发落地说明.md

11 KiB
Raw Blame History

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.5
  • com.github.albfernandez:juniversalchardet:2.4.0
  • org.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.java
  • music-metadata-system/src/main/java/com/music/metadata/domain/metadata/CoverMetadata.java
  • music-metadata-system/src/main/java/com/music/metadata/domain/metadata/MetadataValidationResult.java
  • music-metadata-system/src/main/java/com/music/metadata/domain/metadata/ValidationFailure.java
  • music-metadata-system/src/main/java/com/music/metadata/domain/metadata/ValidationFailureType.java

新增核心服务接口:

  • music-metadata-system/src/main/java/com/music/metadata/service/MetadataReaderService.java
  • music-metadata-system/src/main/java/com/music/metadata/service/MetadataValidatorService.java
  • music-metadata-system/src/main/java/com/music/metadata/service/MetadataSnapshotService.java

3.3 读取层实现

读取相关实现由两层组成:

  1. JaudiotaggerAudioTagExtractor

    • 负责调用 Jaudiotagger 读取底层标签与封面信息
    • 读取核心字段:titleartistalbum_artistalbumtrackyeargenrelyricsdisccomment
    • 汇总全部可枚举标签字段到 fields
    • 针对真实 FLAC 文件上 artwork/特殊字段抛异常的情况做了“尽力而为”兼容处理,避免整个读取流程失败
  2. MetadataReaderServiceImpl

    • 将提取结果组装成 AudioMetadata
    • 自动识别文件格式
    • 检测原始编码并尝试对 GBK/GB18030 类乱码做修复
    • 解析封面格式、尺寸、二进制数据
    • 生成原始元数据 JSON 快照
    • 将快照持久化到 t_metadata_snapshot

关键文件:

  • music-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/AudioTagExtractor.java
  • music-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/AudioTagExtractionResult.java
  • music-metadata-system/src/main/java/com/music/metadata/infrastructure/audio/JaudiotaggerAudioTagExtractor.java
  • music-metadata-system/src/main/java/com/music/metadata/service/impl/MetadataReaderServiceImpl.java

3.4 一票否决校验实现

MetadataValidatorServiceImpl 实现了严格的一票否决制:

  • 编码非 UTF-8 且修复失败,立即返回 ENCODING_ERROR
  • 核心字段按顺序校验:
    • title
    • artist
    • album_artist
    • album
    • track
    • cover
  • 任一字段缺失、乱码或不合规,立即返回失败,不继续后续字段校验

已落地规则包括:

  • 强制 UTF-8 编码门禁
  • track 必须为 序号/总曲目数 格式,例如 01/12
  • 封面必须存在,且格式为 JPG/PNG分辨率不小于 300x300,比例必须 1:1
  • 清洗规则涵盖:
    • 首尾空白与不可见字符处理
    • 非法文件名字符替换
    • 多歌手分隔符统一
    • 英文字段大小写规范化
    • 版本信息从 titlecomment 迁移

关键文件:

  • 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.java
  • music-metadata-system/src/main/java/com/music/metadata/infrastructure/mapper/MetadataSnapshotMapper.java
  • music-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.java
  • music-metadata-system/src/main/java/com/music/metadata/service/impl/ScanFileProcessorImpl.java
  • music-metadata-system/src/main/java/com/music/metadata/service/impl/DeduplicationServiceImpl.java
  • music-metadata-system/src/main/java/com/music/metadata/service/impl/Sha256FileHashServiceImpl.java
  • music-metadata-system/src/main/java/com/music/metadata/service/impl/JaudiotaggerAudioDurationServiceImpl.java

数据库脚本同步新增:

  • t_duplicate_file
  • t_scan_item
  • t_file_process.dedup_key

5. 测试策略

P1 阶段测试分为三层:

5.1 纯单元测试

用于验证 reader、validator 的规则与边界行为:

  • music-metadata-system/src/test/java/com/music/metadata/service/impl/MetadataReaderServiceImplTest.java
  • music-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 读取真实文件
  • 校验 fileFormattitleartistalbumsnapshotJsontagFields、封面二进制与尺寸

如果需要切换目录,也可通过环境变量 REAL_AUDIO_DIR 覆盖默认路径。

5.4 覆盖率补强测试

为满足覆盖率要求,补充了基础设施与低覆盖类测试:

  • music-metadata-system/src/test/java/com/music/metadata/service/impl/CoverageSupportTest.java
  • music-metadata-system/src/test/java/com/music/metadata/service/impl/SimpleServiceImplCoverageTest.java
  • music-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.html
  • music-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 补全等更高层业务能力开发的条件。