基于MediaRecorder与Shazam API的音频识别失效问题排查
问题排查:Shazam API无法识别录制音频的原因及修复方案
核心问题分析
你的代码无法被Shazam API识别的根本原因是录制的音频格式完全不符合API要求:
- 你使用
MediaRecorder的THREE_GPP输出格式和AMR_NB编码器,生成的是带容器的压缩音频文件(3GP格式),而非API要求的原始无封装16位PCM小端数据 - AMR_NB编码器会强制将采样率降到8kHz(即使你设置了44100Hz),且属于可变比特率的有损压缩格式,和API要求的参数完全不匹配
- 你直接读取3GP文件的二进制数据转Base64,本质是把整个封装文件传给API,而非原始音频样本
修复方案
需要改用AudioRecord类直接录制原始PCM数据(MediaRecorder会自动做封装和编码,无法获取原始PCM),以下是修正后的代码实现:
1. 替换为原始PCM录制类
class RawAudioRecorder { private var audioRecord: AudioRecord? = null private var isRecording = false fun startRecording(): ByteArray { // 严格匹配API要求的参数:44100Hz、单声道、16位PCM小端 val sampleRate = 44100 val channelConfig = AudioFormat.CHANNEL_IN_MONO val audioFormat = AudioFormat.ENCODING_PCM_16BIT val minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) audioRecord = AudioRecord( MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, minBufferSize * 2 // 扩大缓冲区避免录制溢出 ) // 预分配5秒的PCM数据空间:44100样本/秒 * 2字节/样本 *5秒 = 441000字节 val audioData = ByteArray(44100 * 2 * 5) var readOffset = 0 audioRecord?.startRecording() isRecording = true // 持续读取PCM数据直到达到预设长度或停止录制 while (isRecording && readOffset < audioData.size) { val bytesRead = audioRecord?.read(audioData, readOffset, audioData.size - readOffset) ?: 0 if (bytesRead < 0) break // 读取错误时终止 readOffset += bytesRead } stopRecording() // 返回实际录制的有效数据 return audioData.copyOf(readOffset) } fun stopRecording() { isRecording = false audioRecord?.stop() audioRecord?.release() audioRecord = null } }
2. 修改录制处理逻辑
private suspend fun launchAudioRecording(context: Context): String { Log.d("SearchingSongScreen", "Starting raw PCM recording") val recorder = RawAudioRecorder() // 在IO线程执行录制,避免阻塞UI线程 val rawPcmData = withContext(Dispatchers.IO) { recorder.startRecording() } Log.d("SearchingSongScreen", "Recorded ${rawPcmData.size} bytes of raw PCM") // 使用NO_WRAP避免Base64编码产生换行符,防止API解析失败 return Base64.encodeToString(rawPcmData, Base64.NO_WRAP) }
3. 关键验证点
- Android的
ENCODING_PCM_16BIT默认就是小端字节序,符合API要求 - 5秒的PCM数据大小约为430KB,小于API限制的500KB
- 可以将录制的PCM数据添加WAV头后保存为文件,用音频工具(如Audacity)检查参数是否正确:44100Hz、单声道、16位
内容的提问来源于stack exchange,提问作者Thibault Verlinde
相关产品推荐
相关产品推荐

