
Vivi-Music音乐识别功能揭秘Shazam指纹算法如何让手机离线提取歌曲指纹【免费下载链接】vivi-musicVivi-Music is an expressive Material 3–based YouTube Music client for Android.项目地址: https://gitcode.com/gh_mirrors/vi/vivi-musicVivi-Music 是一款基于 Material 3 的 YouTube Music 安卓客户端除了流畅的播放体验它还内置了音乐识别功能对着正在播放的音乐录下 10 秒就能认出这首歌。这项能力的核心是移植了Shazam 指纹算法的音频指纹引擎——手机在本地离线提取出歌曲的声音指纹再交由云端完成匹配。本文将带你彻底看懂它的原理与实现。音乐识别是如何工作的录音10秒的四步流程整个识别过程被封装在 MusicRecognitionService.kt 中流程清晰得像一条流水线录音采集调用麦克风录制10 秒单声道音频44100 Hz、16 位 PCM。录 10 秒而不是 3 秒是为了在嘈杂环境下也能保留足够的特征信息重采样通过 AudioResampler.kt 把音频重采样到算法要求的16 kHz标准采样率本地指纹生成这一步完全不依赖网络全部在手机上完成原理见下一节云端匹配把仅几百字节的指纹签名发送给 Shazam 识别接口由 Shazam.kt 完成请求管理。一句话概括录音重采样和指纹提取是离线的只有最后的对答案需要联网。Shazam指纹算法原理给歌曲画一张声音素描指纹引擎的核心是 ShazamSignatureGenerator.kt——一个纯 Kotlin 实现的音频指纹生成器。它的思路可以拆成三步1️⃣ FFT 把声音变成频谱声音本质上是波形而波形很难认人。算法每隔 128 个采样点就取一段音频乘以Hanning 窗减少频谱泄漏再做2048 点快速傅里叶变换FFT把随时间变化的声音转成每个频率有多强的频谱图。代码中内置了一个自己手写的迭代式 Cooley-Tukey FFT见文件内computeRfft函数不依赖任何第三方数学库。2️⃣ 峰值扩散抗噪声的关键设计频谱图上的尖峰才是歌曲的签名。但手机录音会混入噪声某个尖峰可能瞬间被淹没。为此算法做了峰值扩散把每个尖峰的能量向时间和频率两个方向扩散到邻近格子实现见doPeakSpreading函数。这样一来即使部分数据被噪声干扰尖峰也能从邻居处借力存活下来识别鲁棒性大幅提升。3️⃣ 筛选峰值并编码成签名算法只保留 4 个频段内的显著峰值250–520 Hz、520–1450 Hz、1450–3500 Hz、3500–5500 Hz并记录每个峰值的时间 × 幅度 × 频率三元组。最后把这些峰值按特定二进制格式打包、Base64 编码生成一条data:audio/vnd.shazam.sig;base64,...开头的签名串——这正是 Shazam 官方协议格式体积通常只有几百字节。 为什么不用上传整段录音因为指纹已经把这首曲子是谁的全部信息压缩进去了上传签名又快又省流量隐私也更好。Vibra指纹引擎从C到纯Kotlin的演进项目中其实保留了两套指纹引擎这也是源码考古的有趣之处引擎位置说明C 原生版Vibravibrafp/lib/基于知名开源库 Vibra使用 FFTW3 做 FFT通过 JNI 暴露 vibra.h 接口纯 Kotlin 版现役ShazamSignatureGenerator.kt逐位对齐 C 实现摆脱了 NDK/FFTW 依赖启动更快、包体更小Vibra 引擎的构建说明见 vibrafp/README.md它介绍了如何为四种 Android ABIarm64-v8a、armeabi-v7a、x86、x86_64编译 FFTW 静态库。而现役的 Kotlin 版由 VibraSignature.kt 统一封装对外暴露调用方完全无感。云端识别请求的工程细节指纹只是线索最后的匹配在云端完成。shazamkit 模块 的 Shazam.kt 里藏着不少工程巧思对新手很有学习价值限流保护两次请求至少间隔 1 秒最多 2 个并发请求避免触发服务端的 429 限制指数退避重试遇到限流错误后等待 2s → 4s → 8s 递增重试最多 3 次结果缓存相同指纹 5 分钟内直接返回缓存结果连听同一首歌也不用重复请求请求队列最多容纳 50 个待处理请求防止突发流量打爆内存响应解析识别成功后的歌名、歌手、专辑、封面、歌词、流派等信息统一转换为 ShazamModels.kt 中的RecognitionResult模型供界面层展示。常见问题 FAQQ1没有网络时能识曲吗不能。指纹提取确实 100% 离线完成但指纹 → 歌曲的匹配依赖云端数据库没有网络就无法返回结果。准确地说它是离线提取 在线匹配。Q2为什么要录 10 秒会不会太慢10 秒音频能产生更多、更稳定的峰值在背景嘈杂、音量较小时命中率更高。整个过程通常十几秒内就有结果。Q3识别结果会展示哪些信息包括歌名、歌手、专辑、封面图、流派、发行日期、歌词以及关联的流媒体链接见RecognitionResult数据类。Q4识别历史保存在哪识别记录会存入本地数据库实体定义见 RecognitionHistory.kt。源码导读想深挖看哪里想了解去看完整识别流程录音→指纹→请求MusicRecognitionService.ktFFT、峰值扩散、签名编码ShazamSignatureGenerator.kt44.1kHz → 16kHz 重采样AudioResampler.ktC 版指纹库与 FFTW 构建vibrafp/ 及其 README.mdShazam 请求与限流重试Shazam.kt识别界面RecognitionScreen.kt从一段 10 秒的录音到几百字节的数字签名再到云端数据库里的那条歌曲记录——Vivi-Music 用不到几千行代码就把 Shazam 的核心技术搬进了你的手机。希望这篇指南能帮你理解音频指纹的魅力也欢迎动手阅读上述源码亲眼看一看机器是如何听歌识曲的 。【免费下载链接】vivi-musicVivi-Music is an expressive Material 3–based YouTube Music client for Android.项目地址: https://gitcode.com/gh_mirrors/vi/vivi-music创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考