ShazamKit在Android端匹配自定义签名目录返回NoMatch问题排查
问题排查:ShazamKit自定义库匹配失败代码错误点
- 错误1:传入了带WAV头的完整文件数据,而非纯PCM数据
你读入的apple-test-wav.wav是标准WAV格式,文件前44字节是格式描述头,并不是音频PCM数据。ShazamKit的append方法要求传入纯16bit PCM裸流,你把文件头一起传入会导致生成的签名完全失真,自然匹配失败。 - 错误2:时间戳参数传递错误
signatureGenerator.append的第三个参数是当前传入音频块的起始采样时间戳,作用是对齐签名的时间轴,你直接传入System.currentTimeMillis()(当前系统时间)会导致生成的签名时间轴和自定义签名库中的签名完全错位,无法匹配。该参数对于本地文件处理直接传0即可,如果是分片传入,每次传入的时间戳要对应上一段音频的结束时间(单位毫秒)。 - 错误3:缺少核心流程的错误校验
你目前强制将createSignatureGenerator、createSession的返回值强转为Success类型,没有处理失败分支,一旦签名生成器创建异常、自定义签名库加载失败都会导致后续流程异常,你也无法定位具体问题点。另外addFromCatalog方法本身也有返回值,你没有校验它是否加载成功,有可能你的自定义签名库本身就没有正确加载到Catalog中。 - 潜在校验点:采样率对齐验证
你需要确认生成FoodMath.shazamsignature时使用的音频采样率是否和当前代码指定的SAMPLE_RATE_48000完全一致,采样率不匹配也会直接导致签名无法匹配。
修正后参考代码
private suspend fun searchCatalog() { val wavFileStream = context?.assets?.open("apple-test-wav.wav") ?: run { println("音频文件不存在") return } // 跳过44字节WAV头,只取PCM数据 val wavBytes = wavFileStream.readBytes() wavFileStream.close() val pcmBytes = wavBytes.sliceArray(44 until wavBytes.size) // 校验签名生成器创建结果 val generatorResult = ShazamKit.createSignatureGenerator(AudioSampleRateInHz.SAMPLE_RATE_48000) if (generatorResult !is ShazamKitResult.Success) { println("签名生成器创建失败: ${generatorResult.exceptionOrNull()?.message}") return } val signatureGenerator = generatorResult.data // 本地文件处理起始时间戳传0 signatureGenerator.append(pcmBytes, pcmBytes.size, 0) val signature = signatureGenerator.generateSignature() // 加载自定义签名库并校验加载结果 val catalogStream = context?.assets?.open("FoodMath.shazamsignature") ?: run { println("签名库文件不存在") return } val catalog = ShazamKit.createCustomCatalog() val addResult = catalog.addFromCatalog(catalogStream) catalogStream.close() if (addResult.isFailure) { println("签名库加载失败: ${addResult.exceptionOrNull()?.message}") return } // 创建匹配会话并校验 val sessionResult = ShazamKit.createSession(catalog) if (sessionResult !is ShazamKitResult.Success) { println("匹配会话创建失败: ${sessionResult.exceptionOrNull()?.message}") return } val session = sessionResult.data val matchResult = session.match(signature) println("匹配结果: $matchResult") }
内容的提问来源于stack exchange,提问作者Gerard
相关产品推荐
相关产品推荐

