Anni 是如何工作的?
从组成上来说,Anni
分为三个部分:
- 音频文件相关:音频元信息处理、整轨切分、元数据导入/导出
- 音乐仓库相关:仓库结构管理、数据整理
- 服务端/客户端相关
音频文件相关
整轨切分
ArchLinux Wiki
上专门有一页专门介绍如何切分 CUE
,其中用到的就是 shntools
中的 shnsplit
。配合上 cuetools
的 cuetag.sh
,可以相对方便地实现整轨的切分和音频元数据的导入。
笔者持续了这样的切分方式一段时间(如下),但最终还是放弃了。
NAME="${$(ls *.cue)%.cue}" && shnsplit -f "$NAME.cue" -o "flac flac --picture cover.jpg -o %f -" "$NAME.wav" -t "%n. %t"
放弃的原因很大一部分其实源于这个脚本没写好,但实际我也有点厌倦了这种有点复杂的切分方式。虽然 flacon
或许也是个不错的选择,但其默认的设置并不讨喜,首先是会强制把封面图片转小并强制替换,其次是输出标签的 key
都是小写的。
此外,shntool
对 CUE
读取的实现也存在一些问题:其无法识别 UTF-8 With BOM
的文件。隔壁的方案是使用 tail
,于是脚本就变得更加复杂了(笑)
从 Anni
对这方面的支持程度可以看出这个项目成长的轨迹。早期版本实现的是读取 CUE
并输出可工作的 bash
脚本。从本质上来说,这样的工作方式和上面直接用脚本的方式没什么不同,但区别在于:
CUE
的解析更可控了,可以进行一些基于内容的检查- 实现的
CUE
部分还可以用于项目的其他部分
而目前的版本则是基本实现了 shnsplit
的对应功能,可以根据 CUE
切分并输出 wav
、flac
或 ape
格式的音频。Anni
实现了 wav
的解析与切分;而其他格式则是调用对应的解码器解码为 wav
后再进行切分,与 shnsplit
一致。
目前使用的 CUE
解析库为 ProjectAnni/cue_sheet,fork
自 leoschwarz/cue_sheet
。Anni
在这个实现的基础上修复了 REM
解析的问题。
音频元数据处理
音频元数据的可靠来源为发行商的官方网站、歌手的个人主页、企划/组合的官网和 BK
;较可靠来源为 iTunes
上的专辑信息,VGMDB
等数据库收集的非一手资料;次可靠来源为 CUE
中附带的元信息等。
参差不齐的数据需要经过一定的整理后才能写入音频文件,作为自带的元数据存储。由于音频元数据的变动需要修改整个音频文件,更新较为麻烦,因此我们希望尽量减少对音频本身的修改,力求一次到位,将正确的元数据写入后就不再变动。
元数据导入/导出
在整理「THE IDOLM@STER
」的音乐资源时,我拿到的资源是这样的:
- 所有资源均为
FLAC
格式,以罗马音命名 - 有内嵌元数据,但同样有大量罗马音填充
理想的整理方式是这样的:
- 从一个目录的
FLAC
中将专辑的元数据导出到文本 - 和可信源进行对比
- 将整理后的元数据重新导入
FLAC
中
这也是 Anni
目前的分轨整理方式。Anni
的官方仓库位于 ProjectAnni/repo
,目前存放了我制定元数据仓库格式以来整理的所有的专辑信息。
音频仓库相关
音频仓库(Audio Library
)是用于存放音频文件的系统,对目录组织的要求较为松散,但对专辑目录及音轨的命名有着较严格的要求。
元数据仓库(Metadata Repository
)是用于存放音频元数据的仓库,格式要求严格。
在二者的结合下,我们便可以通过 (AlbumID, DiscID, TrackID)
三元组的形式索引 Anni
系统中的所有音频文件。