使用Expo-AV录制的音频无法正常调用Azure语音转文本API
问题:Expo-AV录制音频发送至Azure语音转文本API返回空结果
我使用expo-av录制本地音频,尝试发送到Microsoft Azure Speech-To-Text API,但一直无法得到有效结果。请求返回状态码200(OK),但识别结果始终是空字符串"",仿佛音频内容未被正确解析。我试过用axios替换Expo的uploadAsync,问题依旧。目前怀疑是音频发送方式有误,二进制内容的处理可能存在问题。
当前请求代码
const sendToAzure = async () => { const url = "https://brazilsouth.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=pt-BR" const key = 'my-api-key'; try { const uri = recording.getURI(); const response = await FileSystem.uploadAsync(url, uri, { httpMethod: 'POST', headers: { 'Ocp-Apim-Subscription-Key': key, }, uploadType: FileSystem.FileSystemUploadType.BINARY_CONTENT, }); console.log('Response:', JSON.parse(response.body)); } catch (error) { console.error(error); } }
注:recording状态正常,通过其URI可以正常播放录制的音频,这部分功能没有问题。
解决建议
1. 确保音频格式符合Azure API要求
Azure Speech-To-Text API对音频格式有严格要求,默认支持WAV(PCM编码,16kHz采样率,16位单声道)。Expo-AV默认录制的是AAC格式,需要修改录制选项:
const recordingOptions = { android: { extension: '.wav', outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_LINEAR_PCM, audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_PCM_16BIT, sampleRate: 16000, numberOfChannels: 1, bitRate: 128000, }, ios: { extension: '.wav', audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_HIGH, sampleRate: 16000, numberOfChannels: 1, bitRate: 128000, linearPCMBitDepth: 16, linearPCMIsBigEndian: false, linearPCMIsFloat: false, }, }; // 开始录音时传入该选项 await recording.prepareToRecordAsync(recordingOptions);
2. 添加必要的请求头
Azure API需要Content-Type头来识别音频格式,之前的请求缺少该字段,导致API无法解析内容。修改请求头:
headers: { 'Ocp-Apim-Subscription-Key': key, 'Content-Type': 'audio/wav; codecs=audio/pcm; samplerate=16000' },
3. 验证并正确发送二进制内容
可以先读取音频文件的二进制数据,转换成Blob后再发送,确保内容正确:
const sendToAzure = async () => { const url = "https://brazilsouth.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=pt-BR" const key = 'my-api-key'; try { const uri = recording.getURI(); // 读取音频文件为base64格式 const base64Data = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 }); // 转换为Blob const blob = await fetch(`data:audio/wav;base64,${base64Data}`).then(res => res.blob()); // 发送请求 const response = await fetch(url, { method: 'POST', headers: { 'Ocp-Apim-Subscription-Key': key, 'Content-Type': 'audio/wav; codecs=audio/pcm; samplerate=16000' }, body: blob }); const result = await response.json(); console.log('Response:', result); } catch (error) { console.error(error); } }
4. 确认Azure区域与密钥匹配
检查订阅密钥对应的区域是否为brazilsouth,确保API端点URL和密钥的区域一致,避免跨区域导致的解析失败。
内容的提问来源于stack exchange,提问作者Rodrigo Duarte
相关产品推荐
相关产品推荐

