你的"无损"是真的吗?我用Rust写了个假无损检测器(附开源地址)

2026-06-10 17:55:18 2点赞 6收藏 4评论

写在前面:为什么折腾这个

我攒本地无损音乐库很久了,FLAC、ALAC 一路收下来,硬盘里堆了不少。直到某天我突然冒出个念头:这些标着"无损"的文件,真的都是无损吗?

所谓假无损,就是把一个有损的 mp3(或 aac)解码之后,重新封装成 FLAC 或 ALAC。文件后缀是无损格式没错,体积也撑起来了,但里面的音频内容在当初有损压缩那一步,高频信息就已经被永久丢掉了——套个无损的壳,补不回来。你下载时看到的是 ".flac",听到的其实是被阉割过的版本。

问题是,光看文件名、看体积、甚至用耳朵听,都很难分辨。我翻了一圈现成工具:要么是多年没更新的 Windows 老 GUI,要么是配置一堆依赖的 Python 脚本,要么干脆在我的文件上不工作。作为一个平时写代码的人,索性自己撸一个——纯命令行、能批量扫整个库、扫完出报告。

写完顺手开源了,这篇就连原理带用法分享给同样有强迫症的你。

什么是假无损,以及它为什么能被检测出来

要理解检测原理,得先理解有损压缩干了什么。

mp3、aac 这类有损编码器,为了压缩体积,会把人耳不敏感的信息扔掉,其中很关键的一刀就是高频低通切除:编码器会在某个固定频率以上直接砍掉,几乎不保留能量。不同码率切的位置不同,大致是:

  • 128k mp3:约 16kHz 以上被砍

  • 320k mp3:约 20kHz 以上被砍

真正的无损(比如 16bit/44.1kHz 的 CD 抓轨),高频能量是自然延伸的,会一直分布到接近奈奎斯特频率(44.1kHz 采样率对应约 22kHz)。

所以关键来了:当你把一个 mp3 转成 FLAC,那道"低通切除"的痕迹是抹不掉的。在频谱图上,真无损的高频是平滑延伸到顶的,而假无损会在某个频率上出现一道能量断崖——高于那个频率几乎一片空白。

真无损spek截图真无损spek截图假无损spek截图假无损spek截图

检测思路就顺出来了:对音频做 FFT(快速傅里叶变换)转换到频域,统计能量随频率的分布,找出那道"断崖"在哪。断崖频率高(接近 20kHz)→ 像真无损;断崖明显偏低(16kHz 左右)→ 高度可疑。

工具长什么样、怎么用

技术栈老实交代,给同样写代码的朋友参考:

  • 语言:Rust。主要图它能编译成单个二进制文件,分发零负担,跨平台也干净。

  • 音频解码:symphonia(纯 Rust,支持 FLAC/ALAC/WAV 等,不依赖系统库)

  • 频谱分析:rustfft

  • 并行:rayon,批量扫库时多核并行,几千个文件也不慢

用法分两种。

单个文件——给出详细判断:

cargo run --release -- "藤原さくら - uku FLAC 2026 FLAC/01 Angel.flac" --------------------- 文件: 藤原さくら - uku FLAC 2026 FLAC/01 Angel.flac 格式: FLAC 采样率: 48000 Hz 采样总数: 10039269 奈奎斯特频率: 24000 Hz 估计高频截止: 21850 Hz (91.0% of Nyquist) 频谱空洞: 无明显空洞 判断: ✅ 高频延伸正常,像真无损 (提示:古典乐、人声、老录音本身高频能量就少,可能误报; 建议对可疑文件用 Spek 等工具看一眼频谱图再下结论。

输出会告诉你这个文件的采样率、估计的高频截止频率,以及一个三档判断(✅ 像真无损 / ⚠️ 高频收窄 / 🚩 高度可疑)。

整个目录——递归批量扫描,并行处理,出报告:

cargo run --release -- ~/music --report report.txt --json report.json ---------------------------- 收集音频文件中… (扩展名: flac, wav, m4a, aif, aiff, caf, alac, dsf, dff) 找到 76 个文件,开始扫描… 扫描中… 76/76 文本报告已写入: report.txt JSON 报告已写入: report.json

扫完会生成一份文本报告:汇总统计(多少 ✅、多少 🚩)、按专辑排行、以及完整的可疑文件清单。还能顺带出一份 JSON,方便你自己再处理。

report.jsonreport.jsonreport.txtreport.txt

实测:扫一遍我自己的歌库

光说不练假把式,直接扫我自己的库。

这次一共扫了 2798 首,结果:

  • ✅ 像真无损:2086 首

  • ⚠️ 高频收窄:515 首

  • 🚩 高度可疑:185 首

  • 🔼 假 Hi-Res (上采样) :12 首

  • ✖ 解码失败:0 首

最让我意外的是,可疑文件不是零散分布的,而是扎堆集中在某几张专辑里

这其实带出一个比单文件判断更可靠的洞察:如果一整张专辑的曲子都是同一档位的低截止,那基本可以断定这张专辑的来源就是有损的——单首歌高频少可能是曲风问题,但整张专辑齐刷刷在 16kHz 断崖,不可能是巧合。所以我的报告特意做了"按专辑排行",揪源头比揪单首更准。

局限性:它不是万能的,请这么用

这部分我必须说清楚,免得有人拿它当圣旨乱删文件。

这是启发式判断,不是 100% 准确。 具体有两个已知盲区:

第一,误报。古典乐、纯人声、老录音、专辑里的间奏/skit,这些内容本身高频能量就少,频谱看起来也像被"切"过,但它们是真无损。工具可能把它们标成可疑。

第二,漏报。320k 这种高码率有损,它的截止频率在 20kHz 附近,和真无损的自然高频滚降几乎重叠——这种情况光靠"找截止频率"基本测不出来。这是这个方法的根本局限,不是实现问题。(题外话:有个叫 FLAD 的项目用机器学习、且刻意不依赖 20kHz 以上的信息来绕开这个盲区,思路很值得参考,我后续也想往这个方向改进。)

所以正确用法是:把这个工具当成"批量缩小怀疑范围"的筛子,它帮你从几千首里快速圈出几十个嫌疑犯,然后你再对这些标红的文件,用 Spek 之类的工具看一眼频谱图人工确认,确认了再决定怎么处理。别让工具替你做删除决定。

想验证工具准不准? 教你个自测方法:用 ffmpeg 把一个你确定的真无损文件,转成 mp3 再转回 FLAC,人为造一个"已知是假"的文件,喂给工具看它能不能抓出来:

ffmpeg -i 真无损.flac -b:a 128k temp.mp3 ffmpeg -i temp.mp3 fake_128k.flac

拿 fake_128k.flac 去扫,如果被标 🚩,说明工具在干活。

开源地址与后续

工具已经开源在 GitHub:lossless-checker

欢迎 star、提 issue,有兴趣的也欢迎贡献代码。后续我想做的几件事:把检测做得更鲁棒一些(应对 320k 那个盲区)、做个批量处理的图形界面、以及对接元数据库帮忙顺手整理库。

你的"无损"是真的吗?我用Rust写了个假无损检测器(附开源地址)

如果你也是本地无损党,欢迎扫完自己的库回来评论区报个数——你的歌库里藏了多少水货?

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
4评论

  • 精彩
  • 最新
  • 我也写了一个,中间也看过楼主的文章,看看我的怎么样:
    LosslessChecker 是一款专为音乐爱好者和音频收藏者设计的工具。它能快速分析音频文件,告诉你手上的 FLAC、APE、WAV 等文件究竟是真正的无损音质,还是从 MP3 等有损格式"冒充"上来的。

    讨论:
    去看看
    去看看
    下载:FFmpeg是关键组件,可以用你已经有的ffmpeg.exe,win7能使用的版本是6.1.x,不支持XP

    夸分享了「LosslessChecker」,打开「夸」即可获取。
    /~76993ZO2o9~:/
    链接:去看看

    通过度盘分享的知识:LosslessChecker
    链接: 去看看

    校验提示文案

    提交
  • 思路不错。其实这个年代,可以直接把已知的真无损,和压缩过的音频文件,喂给ai学习,一个很小体量模型就能精准判断了?

    校验提示文案

    提交
    训练数据的质量和覆盖度无法保证的

    校验提示文案

    提交
    收起所有回复
  • 既然耳朵分辨不出,那其实也无妨了!

    校验提示文案

    提交
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
6
扫一下,分享更方便,购买更轻松