Files
music-metadata-system/docs/总方案/音乐元数据标准化与归档系统 需求梳理 + 架构技术方案.md

588 lines
40 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 音乐元数据标准化与归档系统 需求梳理+架构技术方案
**文档版本**V1.0
**修订日期**2026年03月15日
**文档状态**:正式版
**技术约束**后端Java + GraalVM原生编译、前端Vue技术栈
**核心适配**Navidrome音乐服务器官方最佳实践
---
## 一、文档概述
### 1.1 文档目的
本文档完整梳理「音乐元数据标准化与归档系统」的业务需求、架构设计、核心规则、技术实现与落地路径,为系统开发、测试、部署提供全流程指导,确保系统最终实现**元数据零错误识别、目录结构100%适配Navidrome、全流程自动化+人工兜底可控**的核心目标。
### 1.2 适用范围
- 业务范围:个人/家庭级音乐库元数据标准化、自动归档、全生命周期管理
- 技术范围后端Java服务开发、GraalVM原生编译适配、Vue前端可视化界面开发、Navidrome音乐库适配
- 读者对象:开发人员、测试人员、系统运维人员、最终用户
### 1.3 术语定义
| 术语 | 全称 | 说明 |
|------|------|------|
| 元数据 | Music Metadata | 音乐文件内嵌的标签信息,包括歌曲标题、歌手、专辑、封面、曲目编号等核心信息 |
| 音频指纹 | Acoustic Fingerprint | 基于音频内容生成的唯一特征码,不受元数据、格式、比特率影响,用于精准识别歌曲 |
| 归档 | Archiving | 按规范规则重命名文件、生成标准化目录结构,将音乐文件整理到目标音乐库的过程 |
| 增量入库 | Incremental Storage | 仅处理新增的音乐文件,跳过已处理完成的文件,避免重复归档 |
| 原生镜像 | Native Image | 基于GraalVM将Java程序编译为平台相关的可执行文件实现极速启动、低内存占用 |
---
## 二、项目背景与目标
### 2.1 项目背景
个人/家庭音乐库的文件来源多样CD抓取、网络下载、音频转录等普遍存在以下核心痛点
1. 元数据不规范字段缺失、乱码、格式不统一导致Navidrome等流媒体服务器无法正确识别歌手、专辑、封面、歌词等信息
2. 目录结构混乱无统一归档规则文件存放分散Navidrome扫描后出现歌手分裂、专辑错乱、曲目排序错误等问题
3. 重复文件冗余:同一首歌存在多个版本,占用存储空间,音乐库管理混乱
4. 无标准化管理能力:缺失元数据的文件无统一兜底处理流程,最终成为音乐库中的“无效文件”
### 2.2 核心目标
1. **标准化适配**建立严格的元数据校验规则确保处理后的音乐文件100%被Navidrome及主流播放器完整识别
2. **自动化归档**:按预设规则自动完成音乐文件的目录整理、重命名、元数据写入,无需人工干预合规文件
3. **全流程可控**:对不符合规范的文件进行精准标记、全链路记录,通过可视化界面实现人工补全兜底
4. **增量高效处理**:支持重复调用,仅处理新增文件,内置多级去重能力,避免重复入库
5. **高性能轻量化**基于GraalVM实现原生编译实现毫秒级启动、低内存占用适配家庭级单机部署场景
### 2.3 次要目标
1. 支持多格式音频文件的元数据读写,覆盖主流无损/有损音频格式
2. 提供可视化的处理进度监控、处理报告、数据统计能力
3. 不修改、不删除用户原始源文件,保障源文件安全
4. 提供可配置的规则扩展能力,适配不同播放器的元数据规范
---
## 三、需求详细梳理
### 3.1 功能性需求
#### 3.1.1 音乐源接入模块
支持两种核心输入方式,覆盖批量处理与单文件快速处理场景:
1. **本地目录批量接入**
- 支持用户指定本地音乐源目录,支持多级目录递归扫描
- 支持配置文件格式过滤,仅扫描指定后缀的音频文件
- 支持扫描断点续传,异常中断后可从断点继续扫描,无需重新全量扫描
- 支持扫描进度实时反馈,前端展示已扫描文件数、待处理文件数
2. **前端页面文件上传**
- 支持单个/多个音乐文件批量上传,支持拖拽上传
- 支持大文件分片上传,断点续传
- 上传完成后自动触发元数据校验与处理流程
- 支持上传文件格式校验,拒绝非支持的音频格式
#### 3.1.2 元数据解析与校验模块(核心)
1. **全格式元数据解析**支持MP3(ID3v1/v2)、FLAC(Vorbis Comment)、M4A(MP4 Metadata)、OGG、WAV主流音频格式的元数据读取与写入
2. **编码自动检测与校验**自动检测元数据原始编码强制校验是否为UTF-8编码非UTF-8编码且无法正常转换的直接标记失败
3. **一票否决制强制校验**:明确核心必填字段,任一必填字段不满足规范要求,直接标记为处理失败,不进行任何猜测式补全,仅记录失败原因
4. **非必填字段提示**:对建议字段的缺失/不规范进行记录,不影响归档,仅在处理报告中提示用户补全
5. **元数据快照存储**:对所有处理文件的原始元数据进行快照存储,用于后续人工处理溯源与回滚
#### 3.1.3 元数据权威补全模块
仅保留**基于音频指纹的权威API补全**作为唯一自动补全手段,无任何文件名/目录结构的猜测式补全,确保元数据准确性:
1. **音频指纹提取**:对校验失败的文件,自动提取音频指纹,生成唯一特征码
2. **权威API对接**对接AcoustID音频指纹识别API、MusicBrainz开源音乐元数据库API获取歌曲权威元数据
3. **补全数据二次校验**API返回的元数据必须再次通过「一票否决制」强制校验校验通过方可写入文件校验不通过仍标记为失败
4. **API调用限流与容错**内置API调用频率限制、超时重试、异常降级机制避免因第三方API故障导致处理流程中断
#### 3.1.4 文件去重与增量入库模块
1. **多级去重算法**
- 一级快速去重计算文件SHA-256哈希值与数据库中已归档文件哈希比对完全一致直接跳过
- 二级特征去重:哈希不同,但「歌手+歌曲标题+专辑+音频时长」完全一致,标记为疑似重复,进入人工确认队列,不自动归档
- 三级指纹去重:音频指纹一致,判定为同一首歌的不同版本,标记为疑似重复,进入人工确认队列
2. **增量入库能力**
- 每次处理任务启动时,先扫描源目录生成文件哈希清单,与已处理完成的清单比对,仅对新增/修改的文件进行处理
- 支持全量重扫配置,用户可手动触发全量文件重新校验
- 已标记为失败的文件,支持手动触发重新处理,无需重新扫描全目录
#### 3.1.5 自动分类归档模块
严格遵循双规则归档100%适配Navidrome官方推荐最佳实践归档文件默认采用**复制模式**,不修改/删除原始源文件:
1. **一级分类规则**按专辑艺术家名称首字母分为A-Z 26个目录非字母开头中文、数字、符号等的专辑艺术家统一归入`#`目录
2. **底层目录规则**严格遵循Navidrome官方规范最终目录结构为
```
目标音乐库根目录/
├── A/
│ └── 专辑艺术家名称/
│ └── 专辑名称/
│ ├── 01 - 歌曲标题.flac
│ ├── 02 - 歌曲标题.flac
│ ├── cover.jpg
│ └── 01 - 歌曲标题.lrc
├── B/
│ └── 专辑艺术家名称/
...
└── #/
└── 非字母开头专辑艺术家名称/
└── 专辑名称/
└── 01 - 歌曲标题.mp3
```
3. **文件名规范化规则**:统一命名格式为`2位曲目编号 - 歌曲标题.文件扩展名`曲目编号不足2位补前导零去除文件名中不支持的特殊字符
4. **封面与歌词归档规则**
- 封面:必须内嵌到音频文件中,同时在专辑目录下生成`cover.jpg`Navidrome优先读取自动缩放为800x800正方形分辨率格式为JPG
- 歌词支持内嵌LRC时间轴歌词同时在同级目录下生成`与歌曲同名.lrc`文件强制UTF-8编码
5. **归档冲突处理**:目标目录已存在同名文件时,自动比对哈希值,哈希一致则跳过,哈希不一致则保留两个文件并标记冲突,等待人工处理
#### 3.1.6 失败文件统一管理模块(核心兜底)
对所有处理失败的文件进行全生命周期管理,提供可视化人工处理界面,确保所有文件可追溯、可兜底:
1. **失败文件全信息记录**:记录文件原始路径、文件名、哈希值、失败原因、原始元数据快照、失败时间、处理状态
2. **失败原因结构化存储**精准标记失败类型包括必填字段缺失、编码乱码、封面不符合规范、API未匹配、曲目编号格式错误等
3. **可视化列表管理**
- 支持按失败类型、处理状态、时间范围、歌手/专辑名称筛选搜索
- 支持批量重新提交处理、批量删除操作
- 列表展示文件核心信息、失败原因摘要、处理状态、操作按钮
4. **元数据人工编辑页面**
- 内置音频预览播放器,支持试听文件,确认歌曲信息
- 核心必填字段表单编辑,带必填校验与格式校验
- 封面上传/在线搜索获取功能,自动缩放裁剪
- 歌词上传/在线搜索获取功能支持LRC格式校验
- 对接MusicBrainz API提供字段自动补全建议提升人工处理效率
5. **人工处理提交流程**:编辑完成后提交,系统自动重新执行全流程校验,校验通过则完成归档,更新状态为已解决;校验不通过则更新失败原因,返回编辑页面
#### 3.1.7 系统管理模块
1. **基础配置管理**:目标音乐库根目录配置、归档模式(复制/移动配置、封面分辨率配置、API密钥配置、必填字段可配置开关
2. **任务管理**:处理任务的创建、暂停、继续、终止,任务进度实时监控,历史任务记录查询
3. **处理报告**:每次任务完成后生成详细报告,包括处理总数、成功数、失败数、重复数、失败原因统计、文件清单导出
4. **日志管理**:系统操作日志、处理日志、错误日志的查询与导出,支持日志级别配置
5. **数据备份与恢复**:支持系统数据库、配置文件的手动/自动备份与恢复
### 3.2 非功能性需求
1. **性能需求**
- 批量处理能力单机环境下每秒可处理≥5个音频文件不含第三方API调用时间
- 启动速度基于GraalVM原生编译后服务启动时间≤500ms
- 内存占用原生镜像运行时稳态内存占用≤200MB
- 大文件支持支持最大2GB的单音频文件处理
2. **兼容性需求**
- 音频格式兼容MP3、FLAC、M4A、OGG、WAV主流音频格式
- 系统兼容支持Windows、Linux、macOS三大主流操作系统
- Navidrome兼容严格适配Navidrome最新稳定版确保扫描零错误、识别零异常
- 浏览器兼容前端界面支持Chrome、Edge、Firefox主流浏览器
3. **稳定性需求**
- 异常容错:单个文件处理失败不影响整体任务流程,异常文件自动标记并跳过
- 断点续传:扫描、处理、上传流程均支持断点续传,异常中断后可恢复
- 数据安全:不修改、不删除原始源文件,元数据写入前自动备份原始文件
- 服务可用性全年可用率≥99.9%,无内存泄漏、无进程崩溃问题
4. **易用性需求**
- 前端界面简洁直观核心功能3步内可完成操作
- 处理进度可视化,失败原因清晰易懂,人工编辑门槛低
- 提供一键批量处理能力,无需复杂配置即可完成标准化归档
5. **安全性需求**
- 文件操作权限控制:仅对用户授权的目录进行读写操作
- 无网络泄露本地文件处理全程不传输原始音频文件仅音频指纹特征码用于第三方API查询
- 配置加密第三方API密钥等敏感配置采用加密存储
### 3.3 约束条件
1. **技术栈约束**后端必须采用Java语言开发基于GraalVM实现原生编译前端必须采用Vue技术栈开发
2. **兼容性约束**归档目录结构、元数据规范必须严格遵循Navidrome官方最佳实践不得自定义非兼容规则
3. **数据安全约束**:默认采用复制模式归档,禁止未经用户授权修改、删除原始源文件
4. **元数据规则约束**:必填字段不满足规范必须标记为失败,禁止任何无权威来源的猜测式自动补全
---
## 四、整体架构设计
### 4.1 分层架构设计
采用经典的DDD分层架构实现业务与技术解耦便于扩展与维护同时适配GraalVM原生编译要求
| 层级 | 核心职责 | 核心组件 |
|------|----------|----------|
| 接入层 | 负责系统对外的所有接入入口,处理用户请求与文件接入 | Vue前端界面、HTTP接口服务、本地目录扫描器、文件上传服务 |
| 应用层 | 编排核心业务流程,处理事务控制,不包含核心业务规则 | 任务管理服务、文件处理流程编排服务、失败文件管理服务、系统配置服务 |
| 领域层 | 实现系统核心业务规则与领域逻辑,是系统的核心 | 元数据校验规则、归档规则、去重规则、音频指纹识别领域服务、元数据读写领域服务 |
| 基础设施层 | 为上层提供技术能力支撑封装底层技术实现适配GraalVM原生编译 | 文件操作组件、元数据读写组件、音频指纹提取组件、第三方API客户端、数据库访问组件、图片处理组件、日志组件 |
| 数据层 | 负责系统数据持久化与文件存储 | 关系型数据库、本地文件系统、目标音乐库目录 |
### 4.2 核心业务全流程
```mermaid
graph TD
A[任务启动:目录扫描/文件上传] --> B[生成文件清单计算SHA-256哈希]
B --> C{哈希比对:是否已归档?}
C -->|是| D[标记为已重复,跳过处理]
C -->|否| E[读取文件原始元数据,生成快照]
E --> F{核心必填字段校验:是否全部合规?}
F -->|是| G[进入去重二次校验]
F -->|否| H[提取音频指纹调用AcoustID+MusicBrainz API]
H --> I{API是否返回完整合规元数据?}
I -->|是| J[写入API元数据到文件二次校验必填字段]
J --> K{二次校验是否通过?}
K -->|是| G
K -->|否| L[标记为处理失败,记录结构化失败原因]
I -->|否| L
L --> M[存入失败文件数据库,状态为待处理]
M --> N[前端失败管理页面人工编辑补全]
N --> E
G -->{二次去重:是否疑似重复?}
-->|是| O[标记为疑似重复,进入人工确认队列]
-->|否| P[按Navidrome规范生成目录与文件名]
P --> Q[写入标准化元数据、封面、歌词]
Q --> R[复制文件到目标音乐库归档目录]
R --> S[更新数据库,标记为处理完成]
S --> T[任务结束,生成处理报告]
```
### 4.3 部署架构设计
系统支持两种部署模式优先适配家庭用户单机部署场景同时支持Docker容器化部署
#### 4.3.1 单机部署模式(推荐)
基于GraalVM原生镜像部署无需安装JDK环境解压即可运行适配Windows/Linux/macOS
1. 前端Vue项目打包为静态资源内置到后端原生镜像中单文件启动
2. 数据库采用嵌入式H2数据库无需额外安装数据库服务
3. 直接读写本地文件系统,无网络转发损耗,性能最优
#### 4.3.2 Docker容器化部署模式
1. 基于GraalVM原生镜像构建Docker镜像镜像体积小≤100MB启动速度快
2. 支持目录挂载,将源音乐目录、目标音乐库目录、配置目录挂载到宿主机
3. 支持Docker Compose一键部署适配NAS、家庭服务器等Linux环境
---
## 五、元数据标准化核心规则(强制执行)
### 5.1 字段规范与一票否决制
#### 5.1.1 核心必填字段(缺一不可,不满足直接标记失败)
| 字段名 | 英文标识 | 强制规范要求 | Navidrome依赖等级 |
|--------|----------|--------------|--------------------|
| 歌曲标题 | title | 非空、无乱码、UTF-8编码、长度≥1字符去除首尾空格 | ⭐⭐⭐⭐⭐ |
| 歌手 | artist | 非空、无乱码、UTF-8编码、长度≥1字符去除首尾空格 | ⭐⭐⭐⭐⭐ |
| 专辑艺术家 | album_artist | 非空、无乱码、UTF-8编码、长度≥1字符合辑/单曲默认与artist一致必须显式存在 | ⭐⭐⭐⭐⭐ |
| 专辑名 | album | 非空、无乱码、UTF-8编码、长度≥1字符去除首尾空格 | ⭐⭐⭐⭐⭐ |
| 曲目编号 | track | 格式必须为「序号/总曲目数」序号与总曲目数均为正整数序号≤总曲目数序号不足2位补前导零 | ⭐⭐⭐⭐⭐ |
| 专辑封面 | cover | 必须内嵌到音频文件中图片格式为JPG/PNG分辨率≥300x300宽高比1:1 | ⭐⭐⭐⭐⭐ |
#### 5.1.2 建议补充字段(缺失不标记失败,仅提示补全)
| 字段名 | 英文标识 | 规范要求 |
|--------|----------|----------|
| 发行年份 | year | 4位数字格式范围1900-当前年份 |
| 流派 | genre | 标准音乐流派术语,多个流派用分号分隔 |
| 歌词 | lyrics | UTF-8编码支持LRC时间轴格式内嵌到音频文件中 |
| 光盘编号 | disc | 格式为「序号/总光盘数」,多光盘专辑必填 |
| 备注 | comment | 用于记录版本信息Live/Remix等无乱码 |
### 5.2 元数据清洗强制规则
仅对合规字段进行标准化清洗,不修改字段核心含义,清洗后仍需满足必填规范:
1. **编码规范**所有元数据强制转换为UTF-8编码无法正常转换、出现乱码的字段直接标记失败
2. **特殊字符处理**:去除字段首尾空格、换行符、不可见特殊字符;目录/文件名不支持的字符`\ / : * ? " < > |`统一替换为`_`
3. **分隔符规范**:多个歌手/流派统一用英文分号+空格`; `分隔,替换原有的`&`、`feat.`、`/`等分隔符
4. **大小写规范**英文单词首字母大写特殊冠词a/an/the句中非首字母小写统一格式
5. **版本信息规范**歌曲标题中的Live/Remix/伴奏等版本信息统一移至comment字段标题仅保留歌曲核心名称
### 5.3 唯一自动补全规则
仅支持**基于音频指纹的权威API补全**,禁止任何基于文件名、目录结构的猜测式补全:
1. 补全数据源仅认可AcoustID+MusicBrainz返回的权威元数据其他第三方数据源不纳入自动补全范围
2. API返回的元数据必须完整覆盖所有核心必填字段且符合规范要求方可自动写入
3. 写入前必须进行二次校验,任一必填字段不满足规范,仍标记为失败,不进行部分字段补全
4. 人工编辑场景下可提供MusicBrainz API搜索建议由用户手动确认后写入不自动覆盖
---
## 六、数据库设计
采用嵌入式H2数据库适配GraalVM原生编译支持单机运行无需额外部署核心表结构如下
### 6.1 文件处理记录表t_file_process
记录所有文件的全流程处理信息,是系统的核心主表
| 字段名 | 数据类型 | 主键 | 非空 | 说明 |
|--------|----------|------|------|------|
| id | BIGINT | 是 | 是 | 自增主键 |
| file_hash | VARCHAR(64) | 否 | 是 | 文件SHA-256哈希值唯一索引 |
| source_file_path | VARCHAR(1000) | 否 | 是 | 原始源文件完整路径 |
| source_file_name | VARCHAR(200) | 否 | 是 | 原始文件名 |
| file_extension | VARCHAR(10) | 否 | 是 | 文件扩展名 |
| file_size | BIGINT | 否 | 是 | 文件大小(字节) |
| audio_duration | INT | 否 | 否 | 音频时长(秒) |
| raw_metadata | TEXT | 否 | 是 | 原始元数据快照JSON格式存储 |
| process_status | VARCHAR(20) | 否 | 是 | 处理状态PENDING(待处理)/PROCESSING(处理中)/SUCCESS(已完成)/FAIL(处理失败)/DUPLICATE(已重复)/CONFLICT(冲突) |
| fail_reason | TEXT | 否 | 否 | 失败原因结构化JSON格式存储 |
| target_file_path | VARCHAR(1000) | 否 | 否 | 归档后目标文件完整路径 |
| task_id | BIGINT | 否 | 是 | 所属处理任务ID |
| created_at | DATETIME | 否 | 是 | 记录创建时间 |
| updated_at | DATETIME | 否 | 是 | 最后更新时间 |
### 6.2 失败文件管理表t_fail_file
专门存储处理失败的文件信息,用于人工兜底处理
| 字段名 | 数据类型 | 主键 | 非空 | 说明 |
|--------|----------|------|------|------|
| id | BIGINT | 是 | 是 | 自增主键 |
| file_process_id | BIGINT | 否 | 是 | 关联文件处理记录表ID外键 |
| file_hash | VARCHAR(64) | 否 | 是 | 文件SHA-256哈希值唯一索引 |
| source_file_path | VARCHAR(1000) | 否 | 是 | 原始源文件完整路径 |
| file_name | VARCHAR(200) | 否 | 是 | 文件名 |
| fail_type | VARCHAR(50) | 否 | 是 | 失败类型MISSING_FIELD(字段缺失)/ENCODING_ERROR(编码乱码)/COVER_INVALID(封面无效)/API_NO_MATCH(API未匹配)/TRACK_FORMAT_ERROR(曲目格式错误)/OTHER(其他) |
| fail_detail | TEXT | 否 | 是 | 失败详细原因结构化JSON格式 |
| raw_metadata | TEXT | 否 | 是 | 原始元数据快照JSON格式 |
| edit_metadata | TEXT | 否 | 否 | 人工编辑后的元数据草稿JSON格式 |
| status | VARCHAR(20) | 否 | 是 | 处理状态PENDING(待处理)/EDITING(编辑中)/RESOLVED(已解决)/DISCARDED(已废弃) |
| created_at | DATETIME | 否 | 是 | 失败记录创建时间 |
| updated_at | DATETIME | 否 | 是 | 最后编辑时间 |
| resolved_at | DATETIME | 否 | 否 | 解决时间 |
### 6.3 处理任务表t_process_task
记录每次批量处理任务的信息,用于任务管理与进度追踪
| 字段名 | 数据类型 | 主键 | 非空 | 说明 |
|--------|----------|------|------|------|
| id | BIGINT | 是 | 是 | 自增主键 |
| task_name | VARCHAR(100) | 否 | 是 | 任务名称 |
| task_type | VARCHAR(20) | 否 | 是 | 任务类型DIR_SCAN(目录扫描)/UPLOAD(文件上传)/REPROCESS(重新处理) |
| source_path | VARCHAR(1000) | 否 | 否 | 源目录路径(目录扫描任务) |
| total_file_count | INT | 否 | 是 | 总文件数 |
| processed_count | INT | 否 | 是 | 已处理文件数 |
| success_count | INT | 否 | 是 | 处理成功数 |
| fail_count | INT | 否 | 是 | 处理失败数 |
| duplicate_count | INT | 否 | 是 | 重复文件数 |
| task_status | VARCHAR(20) | 否 | 是 | 任务状态RUNNING(运行中)/PAUSED(已暂停)/FINISHED(已完成)/TERMINATED(已终止)/ERROR(异常中断) |
| start_time | DATETIME | 否 | 是 | 任务启动时间 |
| end_time | DATETIME | 否 | 否 | 任务结束时间 |
| created_by | VARCHAR(50) | 否 | 是 | 创建人 |
| remark | VARCHAR(500) | 否 | 否 | 任务备注 |
### 6.4 系统配置表t_system_config
存储系统全局配置信息,支持可视化配置修改
| 字段名 | 数据类型 | 主键 | 非空 | 说明 |
|--------|----------|------|------|------|
| id | BIGINT | 是 | 是 | 自增主键 |
| config_key | VARCHAR(100) | 否 | 是 | 配置键,唯一索引 |
| config_value | TEXT | 否 | 否 | 配置值 |
| config_name | VARCHAR(100) | 否 | 是 | 配置名称 |
| config_desc | VARCHAR(500) | 否 | 否 | 配置描述 |
| is_editable | TINYINT | 否 | 是 | 是否可前端编辑0-否1-是 |
| created_at | DATETIME | 否 | 是 | 创建时间 |
| updated_at | DATETIME | 否 | 是 | 最后更新时间 |
---
## 七、技术栈选型与实现方案
### 7.1 后端技术栈Java + GraalVM
| 技术组件 | 选型 | 版本要求 | 选型说明 |
|----------|------|----------|----------|
| 核心框架 | Spring Boot 3.x | ≥3.2.0 | 原生支持GraalVM Native Image生态完善适配嵌入式开发 |
| 原生编译支持 | Spring Native | 与Spring Boot版本一致 | 官方提供的GraalVM原生编译适配方案解决反射、动态代理等原生镜像兼容问题 |
| 数据库访问 | MyBatis-Plus | ≥3.5.5 | 轻量级ORM框架适配GraalVM原生编译简化数据库操作 |
| 嵌入式数据库 | H2 Database | ≥2.2.224 | 嵌入式关系型数据库,无需额外部署,单文件运行,完美适配原生镜像 |
| 元数据读写 | Jaudiotagger | ≥2.2.7 | 业界主流Java音频元数据处理库支持全格式音频标签读写API简单易用 |
| 编码检测 | juniversalchardet | ≥2.4.0 | Mozilla开源编码检测库自动识别元数据原始编码适配中文/日文等多语言 |
| 音频指纹提取 | AcoustID4J + FFmpeg | 最新稳定版 | AcoustID4J对接指纹识别APIFFmpeg提取音频特征适配全格式音频 |
| 图片处理 | Thumbnailator | ≥0.4.20 | 轻量级图片处理库支持封面缩放、裁剪、格式转换API简洁适配原生编译 |
| HTTP客户端 | Spring Cloud OpenFeign | 最新稳定版 | 声明式HTTP客户端对接第三方API适配GraalVM原生编译 |
| 文件上传 | Spring Boot Standard Servlet | 原生支持 | 支持大文件分片上传、断点续传,适配大音频文件处理 |
| 日志框架 | Logback | 与Spring Boot版本一致 | 适配原生编译,高性能日志框架,支持日志分级、滚动输出 |
#### 7.1.1 GraalVM原生编译核心实现方案
1. **环境要求**GraalVM JDK 21+安装Native Image组件
2. **原生镜像适配**
- 对反射类、动态代理类、资源文件提前注册到`reflect-config.json`、`proxy-config.json`、`resource-config.json`配置文件中
- 使用Spring Boot 3.x原生AOT提前处理在编译期生成代理类、解析注解避免运行期反射导致的原生镜像兼容问题
- 对第三方库Jaudiotagger、juniversalchardet等进行原生镜像适配解决第三方库的反射、资源加载问题
3. **构建命令**通过Spring Boot Maven插件一键构建原生镜像命令如下
```bash
mvn clean native:compile -Pnative
```
4. **产物输出**构建完成后生成平台相关的可执行文件无需JDK环境直接双击即可运行
### 7.2 前端技术栈Vue
| 技术组件 | 选型 | 版本要求 | 选型说明 |
|----------|------|----------|----------|
| 核心框架 | Vue 3 | ≥3.4.0 | 组合式API性能优异生态完善符合用户技术栈要求 |
| 构建工具 | Vite | ≥5.0.0 | 极速冷启动、热更新,开发体验优异,打包体积小 |
| UI组件库 | Element Plus | ≥2.6.0 | 适配Vue 3组件丰富界面美观支持暗黑模式适配桌面端管理系统 |
| 状态管理 | Pinia | ≥2.1.0 | Vue 3官方推荐状态管理库轻量简洁支持TypeScript |
| 路由管理 | Vue Router | ≥4.2.0 | Vue官方路由库适配Vue 3支持嵌套路由、路由守卫 |
| HTTP请求 | Axios | ≥1.6.0 | 业界主流HTTP客户端支持请求拦截、响应拦截、超时重试 |
| 文件上传 | vue-simple-uploader | ≥1.0.0 | 支持大文件分片上传、断点续传、拖拽上传,适配大音频文件 |
| 音频播放 | vue3-audio | 最新稳定版 | 适配Vue 3的音频播放器组件支持文件预览试听 |
| 图表可视化 | ECharts | ≥5.4.0 | 百度开源图表库,性能优异,支持处理报告数据可视化展示 |
| 代码规范 | TypeScript + ESLint | 最新稳定版 | 类型安全,代码规范统一,提升可维护性 |
#### 7.2.1 前端核心页面设计
1. **仪表盘首页**:展示音乐库统计数据、近期任务处理情况、失败文件数量、磁盘占用情况,核心功能快捷入口
2. **任务管理页面**:处理任务的创建、暂停、继续、终止,任务进度实时展示,历史任务查询,处理报告查看与导出
3. **文件上传页面**:支持单个/多个文件拖拽上传,上传进度展示,上传完成后自动触发处理流程
4. **失败文件管理页面**:失败文件列表筛选、搜索,批量操作,人工编辑入口,处理状态跟踪
5. **元数据编辑页面**:音频预览播放器,元数据表单编辑,封面上传/搜索,歌词上传/搜索,校验与提交功能
6. **系统配置页面**全局配置可视化编辑包括目标音乐库目录、归档模式、封面规格、API密钥配置等
7. **日志管理页面**:系统日志查询、筛选、导出,日志级别配置
---
## 八、核心API接口设计
采用RESTful风格设计统一返回格式适配前后端分离架构核心接口如下
### 8.1 统一返回格式
```json
{
"code": 200,
"message": "操作成功",
"data": {},
"timestamp": 1710000000000
}
```
- 成功状态码200
- 业务异常状态码400-499
- 系统异常状态码500
### 8.2 核心接口清单
| 接口分类 | 请求方式 | 接口路径 | 接口说明 |
|----------|----------|----------|----------|
| 任务管理 | POST | /api/v1/task/create-dir-task | 创建目录扫描处理任务 |
| 任务管理 | GET | /api/v1/task/list | 分页查询任务列表 |
| 任务管理 | GET | /api/v1/task/{id}/detail | 查询任务详情与进度 |
| 任务管理 | PUT | /api/v1/task/{id}/pause | 暂停任务 |
| 任务管理 | PUT | /api/v1/task/{id}/resume | 继续任务 |
| 任务管理 | PUT | /api/v1/task/{id}/terminate | 终止任务 |
| 任务管理 | GET | /api/v1/task/{id}/report | 获取任务处理报告 |
| 文件上传 | POST | /api/v1/file/upload | 音频文件分片上传 |
| 文件上传 | POST | /api/v1/file/upload/merge | 分片上传完成后合并文件 |
| 元数据处理 | POST | /api/v1/metadata/validate | 手动校验文件元数据合规性 |
| 元数据处理 | POST | /api/v1/metadata/reprocess/{id} | 重新处理指定失败文件 |
| 失败文件管理 | GET | /api/v1/fail-file/list | 分页查询失败文件列表 |
| 失败文件管理 | GET | /api/v1/fail-file/{id}/detail | 查询失败文件详情与原始元数据 |
| 失败文件管理 | PUT | /api/v1/fail-file/{id}/edit | 保存人工编辑的元数据草稿 |
| 失败文件管理 | POST | /api/v1/fail-file/{id}/submit | 提交编辑后的元数据,重新触发处理流程 |
| 失败文件管理 | POST | /api/v1/fail-file/batch-reprocess | 批量重新处理失败文件 |
| 系统配置 | GET | /api/v1/config/list | 查询系统配置列表 |
| 系统配置 | PUT | /api/v1/config/update | 更新系统配置 |
| 系统配置 | POST | /api/v1/config/backup | 手动备份系统配置与数据库 |
---
## 九、部署与运维方案
### 9.1 环境要求
#### 9.1.1 开发环境
| 组件 | 版本要求 |
|------|----------|
| JDK | GraalVM JDK 21+ |
| Maven | ≥3.9.0 |
| Node.js | ≥18.0.0 |
| FFmpeg | 最新稳定版 |
| 操作系统 | Windows 10+/macOS 12+/Linux 内核4.15+ |
#### 9.1.2 生产环境(原生镜像运行)
| 组件 | 最低要求 | 推荐配置 |
|------|----------|----------|
| CPU | 2核4线程 | 4核8线程 |
| 内存 | 512MB | 2GB |
| 磁盘 | 剩余空间≥1GB | 剩余空间≥10GB与音乐库大小匹配 |
| 操作系统 | Windows 10+/macOS 12+/Linux 内核4.15+ | Linux 64位NAS/家庭服务器) |
| 依赖 | FFmpeg音频指纹提取 | FFmpeg最新稳定版 |
### 9.2 部署步骤
#### 9.2.1 原生镜像单机部署Windows/Linux/macOS
1. **构建原生镜像**通过Maven命令构建对应平台的原生可执行文件
2. **环境准备**目标机器安装FFmpeg配置环境变量
3. **文件部署**:将可执行文件、配置文件、数据库目录复制到目标机器
4. **配置修改**修改application.yml配置文件设置目标音乐库目录、API密钥等配置
5. **服务启动**
- Windows双击可执行文件即可启动
- Linux/macOS赋予执行权限后`./music-metadata-tool`启动
6. **访问验证**:浏览器访问`http://localhost:8080`,进入前端管理界面
#### 9.2.2 Docker容器化部署
1. **构建Docker镜像**基于GraalVM原生镜像构建Docker镜像Dockerfile示例如下
```dockerfile
# 构建阶段
FROM ghcr.io/graalvm/graalvm-community:21 AS builder
WORKDIR /app
COPY . .
RUN gu install native-image
RUN mvn clean native:compile -Pnative -DskipTests
# 运行阶段
FROM alpine:3.19
WORKDIR /app
# 安装依赖
RUN apk add --no-cache ffmpeg libc6-compat
# 复制原生可执行文件
COPY --from=builder /app/target/music-metadata-tool /app/music-metadata-tool
# 复制配置文件
COPY src/main/resources/application.yml /app/config/application.yml
# 暴露端口
EXPOSE 8080
# 挂载目录
VOLUME ["/app/config", "/app/data", "/music/source", "/music/library"]
# 启动命令
ENTRYPOINT ["/app/music-metadata-tool", "--spring.config.location=/app/config/application.yml"]
```
2. **Docker Compose部署**编写docker-compose.yml文件一键启动服务
3. **目录挂载**:将源音乐目录、目标音乐库目录、配置目录、数据目录挂载到宿主机
4. **启动服务**`docker-compose up -d`启动容器,浏览器访问对应端口即可使用
### 9.3 运维方案
1. **日志管理**系统日志按天滚动输出保留30天日志支持日志级别动态调整异常日志自动标记告警
2. **数据备份**:支持手动/自动备份数据库与配置文件默认每天凌晨自动备份保留最近7个备份文件
3. **监控告警**内置服务健康检查接口支持Prometheus监控指标采集磁盘空间不足、任务异常失败时自动告警
4. **版本升级**原生镜像版本升级只需替换可执行文件重启服务即可完成兼容历史数据Docker版本升级只需替换镜像版本
5. **故障恢复**:提供数据库恢复、配置回滚功能,任务异常中断后可自动恢复,无需重新全量处理
---
## 十、测试方案
### 10.1 单元测试
- 测试范围:核心领域层逻辑,包括元数据校验规则、去重算法、归档规则、编码转换等核心方法
- 测试框架JUnit 5 + Mockito
- 覆盖率要求核心业务逻辑代码覆盖率≥90%
- 重点测试场景:必填字段校验、边界值测试、异常场景测试、编码转换测试
### 10.2 集成测试
- 测试范围第三方API对接、元数据读写、数据库操作、文件操作等组件集成能力
- 重点测试场景AcoustID/MusicBrainz API对接、音频文件元数据写入与读取、数据库CRUD操作、大文件上传与处理
### 10.3 功能测试
| 测试模块 | 核心测试点 |
|----------|------------|
| 音乐源接入 | 多级目录递归扫描、断点续传、大文件分片上传、格式过滤、异常文件拒绝 |
| 元数据校验 | 必填字段一票否决、编码乱码识别、格式规范校验、合规文件正常通过 |
| 元数据补全 | API正常补全、补全数据二次校验、API异常容错、无猜测式补全 |
| 去重与增量入库 | 哈希去重、特征去重、增量文件识别、重复文件跳过、异常去重处理 |
| 自动归档 | 目录结构生成、文件名规范化、封面/歌词归档、Navidrome适配、冲突处理 |
| 失败文件管理 | 失败原因记录、列表筛选、人工编辑、重新提交流程、批量操作 |
| 系统管理 | 配置修改、任务管理、处理报告生成、日志查询、数据备份与恢复 |
### 10.4 兼容性测试
1. **音频格式兼容**覆盖MP3、FLAC、M4A、OGG、WAV格式的元数据读写与处理测试
2. **系统兼容**Windows、Linux、macOS三大操作系统的原生镜像部署与运行测试
3. **Navidrome兼容**处理后的音乐库导入Navidrome最新稳定版验证扫描识别率、歌手/专辑/封面/歌词展示、曲目排序等核心场景
4. **浏览器兼容**Chrome、Edge、Firefox主流浏览器的前端界面功能测试
### 10.5 性能测试
- 批量处理性能1000个音频文件批量处理验证处理速度、内存占用、CPU使用率
- 启动性能原生镜像启动时间测试验证是否≤500ms
- 大文件处理2GB单音频文件上传、处理、归档全流程测试
- 并发性能:多个任务同时运行,验证系统稳定性与处理能力
---
## 十一、风险与应对措施
| 风险类型 | 风险描述 | 风险等级 | 应对措施 |
|----------|----------|----------|----------|
| 技术风险 | GraalVM原生镜像第三方库兼容问题部分库存在反射、动态代理导致的编译失败 | 中 | 1. 提前对第三方库进行原生镜像适配验证2. 优先选择支持GraalVM原生镜像的库3. 提前注册反射、代理配置通过Spring AOT提前处理 |
| 业务风险 | 第三方API调用限流、故障导致元数据补全失败 | 中 | 1. 内置API调用限流、超时重试机制2. 提供API密钥配置用户可使用自己的密钥3. 异常时直接标记失败,不中断整体任务,后续支持手动重试 |
| 数据风险 | 元数据写入导致音频文件损坏、原始文件丢失 | 高 | 1. 默认采用复制模式不修改原始源文件2. 元数据写入前自动备份源文件3. 写入后校验文件完整性异常时自动回滚4. 提供移动模式开关,用户手动确认后开启 |
| 性能风险 | 超大音乐库10万+文件)全量扫描与处理性能瓶颈 | 中 | 1. 多线程并发处理可配置线程数2. 扫描与处理流程解耦异步处理3. 哈希比对优化建立哈希索引提升去重速度4. 断点续传,支持分批次处理 |
| 兼容性风险 | 小众音频格式元数据读写异常 | 低 | 1. 优先适配主流音频格式小众格式提前校验不支持的格式直接标记失败2. 完善异常捕获,单个文件处理失败不影响整体任务 |
| 安全风险 | 目录越权访问,误操作非授权目录文件 | 高 | 1. 目录白名单机制仅对用户授权的目录进行读写2. 严格校验文件路径禁止路径穿越3. 默认只读访问源目录,仅对目标目录有写入权限 |
---
## 十二、阶段文档索引与实施说明
为避免总方案文档随着阶段推进不断膨胀P0、P1 及后续阶段的“开发落地说明、测试结果、验收证据、偏差说明”统一沉淀到项目仓库内的阶段文档中;本总文档仅保留全局设计、总体规则、阶段索引与里程碑说明。
### 12.1 文档组织规则
- 总方案文档:保留项目背景、需求、总体架构、统一规则、阶段规划
- 阶段落地文档:写入每个阶段的实现内容、关键文件、测试策略、验收结果、已知偏差
- 阶段落地文档统一存放于:`music-metadata-system/docs/`
### 12.2 当前阶段文档索引
| 阶段 | 文档 | 说明 |
|------|------|------|
| P0 | `music-metadata-system/docs/P0-基础架构-开发落地说明.md` | 记录基础架构、数据库底座、统一异常与响应规范的落地情况 |
| P1 | `music-metadata-system/docs/P1-元数据解析与校验-开发落地说明.md` | 记录元数据读取、快照存储、一票否决校验、真实文件测试与覆盖率结果 |
### 12.3 当前状态摘要
- P0 已完成基础工程、数据库底座、基础持久化层和统一异常处理能力建设
- P1 已完成元数据读取、编码检测与修复尝试、快照持久化、一票否决校验、目录扫描与去重相关验收能力
- 详细实现、测试与验收结果请以对应阶段文档为准
## 十三、项目里程碑规划
| 阶段 | 周期 | 核心交付物 | 完成标准 |
|------|------|------------|----------|
| 第一阶段:需求确认与架构设计 | 1周 | 需求规格说明书、架构设计文档、数据库设计文档、API接口文档 | 需求与架构方案确认完成,核心规则与技术选型敲定 |
| 第二阶段:核心后端模块开发 | 3周 | 元数据解析与校验模块、文件去重模块、自动归档模块、API对接模块、数据库访问层 | 核心业务流程可跑通音频文件可完成标准化校验与归档适配Navidrome规范 |
| 第三阶段:前端界面开发 | 2周 | Vue前端工程、所有核心页面、前后端接口联调 | 前端界面可正常访问,所有功能可通过界面操作完成 |
| 第四阶段GraalVM原生编译适配 | 1周 | 原生镜像适配配置、可执行文件构建脚本、Docker镜像构建文件 | 可正常构建对应平台的原生镜像,镜像可正常启动与运行,无兼容问题 |
| 第五阶段测试与Bug修复 | 2周 | 测试用例、测试报告、Bug修复记录 | 完成所有测试场景核心功能无Bug系统稳定运行性能达标 |
| 第六阶段:部署与上线 | 1周 | 部署文档、用户操作手册、正式版安装包、Docker镜像 | 系统可正常部署运行,用户可通过手册完成操作,正式版交付 |
| 合计 | 10周 | 完整系统、全量文档、交付物 | 系统所有功能实现,满足所有需求与约束条件,可正式投入使用 |