给动机录音做备份时,我把「同名不同版本」的坑踩了一遍

上个月整理硬盘,发现一个尴尬的事实:同一段八小节动机,我在三个地方存了七个版本,文件名从 idea_0712.m4a 到 idea_0712_最终.m4a、idea_0712_最终2.m4a,最后一次修改时间横跨四个月。用的是 macOS 14.5,录音来源杂:手机语音备忘录、Logic 里导出的 48kHz WAV、还有两次用 Audio Hijack 抓的系统内录。总共约 9.2GB,1600 多个文件。想做个干净备份前,得先把「哪些是同一段的变体」分出来,不然备份只是把混乱复制一遍。

我的做法很土:先不按文件名,按音频指纹分组。用 ffmpeg 统一转成 16kHz 单声道,再算一个粗糙的频谱均值向量当签名。命令片段如下,可以直接改路径跑:

for f in ~/Motifs/**/*.{m4a,wav,mp3}; do
  base=$(basename "$f")
  ffmpeg -v error -i "$f" -ac 1 -ar 16000 -t 60 \
    -f s16le - | sha1sum | cut -d' ' -f1
  echo "$base"
done

注意 -t 60 是故意截前 60 秒,因为多数动机短于这个长度,长录音里前 60 秒往往能覆盖主段。算出来的哈希只用来做「候选分组」,不追求精确匹配。

为什么这样做:文件名和修改时间都不可靠。手机导出的文件时间会乱,最终 后缀更是自我欺骗;但音频内容本身骗不了人。代价是这方法对「同段动机不同调性、不同速度」不敏感,会把它们分到不同组——这正好是我想要的,因为调性版本我确实想分开存。

哪里会失效:第一,前 60 秒如果包含说话、环境噪音或空白,哈希会完全不同,同一段动机也会被拆开;我后来改成先跑 silencedetect 跳过静音段再算。第二,sha1sum 对浮点误差零容忍,同一文件从不同设备导出,即使听感一样,哈希也几乎不会撞上。所以它只能当「分堆」的起点,不能当「去重」的终点。第三,** 通配在默认 zsh 下行为不同,我一开始漏了一半文件,后来显式用 find 才对齐。

现在我的备份结构是:一个 _raw 原样不动,一个 _grouped 按指纹分文件夹,每个组里保留最早时间和最大码率的版本,其余进 _archive。还没解决的是跨调性版本的命名,目前只能手动听。你们遇到同名不同版本的动机时,是留着全部还是只留一个?

0
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。