跳转到内容

导入流水线

导入把一个文件夹转成准确到发行的目录项,不修改文件的任何一个字节。本页是使用指南所述流程背后的流水线。

监视文件夹由平台文件系统事件监控,经过防抖,并在更改时重新扫描;扫描会与现有候选列表对齐,而不是从头开始。扫描器会把文件夹分类为一个发行(音频直接在其中,或像 CD1/CD2 这样的碟形子文件夹),或把它作为合集递归进入。文件按扩展名分类为音频、图像和文档,然后探测音频:真正重要的 codec 是 FFmpeg 在字节中找到的,而不是文件扩展名。包含 partial-download marker 的文件夹会被排除,直到下载完成。

CUE sheet 会把一个音频镜像转成曲目列表。解析器处理 pregap 和 postgap、每轨 performers 和 ISRC,以及单文件镜像和每轨一文件 CUE 布局。曲目边界会从 CUE frames(1/75 秒)转换为精确采样位置,之后成为播放使用的字节窗口和采样窗口。

识别会在一次遍历中从文件夹里读取三类证据:

  • disc ID,CD 精确曲目布局的 MusicBrainz 指纹,由抓轨日志或 CUE sheet 计算;
  • barcodes,由平台 vision framework 从图像扫描中解码,并从 CUE catalog fields 读取;
  • text:来自图像 OCR、文件夹和文件名、以及抓轨文本文件的目录号和自由文本。

嵌入式音频标签被刻意排除在证据之外:它们描述的是打标签者相信的内容,不是压制本身。(当用户以未知发行导入时,它们会给回退元数据提供初始值。)

Disc ID 和条码会并发查找,disc ID 对照 MusicBrainz,条码同时对照 MusicBrainz 和 Discogs,并对结果做交叉定位:同意同一发行组的结果会汇合,目录号匹配会缩小压制列表,信号之间的不一致会作为显式冲突呈现给用户,而不是静默选择最佳猜测。每个结果都携带其来源(由 disc ID、条码、catalog match 找到),因此 UI 可以说明为什么提供这一行。

MusicBrainz 以匿名方式查询,并严格保持每秒一个请求的节奏。Discogs 使用用户保存在 keyring 中的个人 token 认证,在其速率限制内控制节奏并重试;被拒绝的 token 会如实报告,因此 UI 可以标记它,而不是让搜索安静失败。响应按会话缓存,获胜来源的原始 JSON 会归档进数据库,以便将来重新解释。

确认导入会按顺序运行:

  1. 解码验证:每一轨从头到尾解码;无法完整解码的抓轨会在写入任何内容前导入失败(一个 config flag 可以禁用此项)。
  2. 响度分析:在同一次解码遍历中测量每轨和每专辑的 integrated loudness 与 true peak,并存储以供 replay-gain 使用。
  3. 封面选择:所选图像(远程、文件夹图片或内嵌图像)重新渲染为显示缩略图;如果原图来自文件夹,它会保留在发行文件中。
  4. 原子写入:release、tracks、credits、identities、formats、segments、files 和 cover 在一个 transaction 中提交。不存在半导入状态。

发行落库时原位引用用户文件。如果用户选择云端托管,上传会在提交后作为存储转换发生,并且文件原始字节始终是真相来源;用户交给 bae 的任何内容都不会被删除或改动。

每个发行都会记录其导入文件夹结构的 content hash(相对路径和大小,与位置无关)。重新扫描用它标记已在资料库中的文件夹,同一抓轨的重新导入也用它找到并替换先前发行,而不是复制一份。