Flask字母识别API无法加载Android录音:Librosa格式识别失败
解决Flask API中Librosa无法加载Android录制WAV文件的问题
问题分析
你的核心问题有两个:
- Librosa无法直接处理Flask的
FileStorage对象,需要先将其转换为可读取的文件流或临时文件 - Android设备录制的WAV文件通常采用IMA ADPCM压缩编码,而Librosa依赖的Soundfile仅原生支持未压缩的PCM编码WAV,这会导致格式识别失败
解决方案
下面是修改后的完整代码,结合临时文件处理+强制转码为PCM WAV的方案,确保Librosa能正常加载:
import os import tempfile from pydub import AudioSegment import librosa import numpy as np import statistics from flask import Flask, request, jsonify app = Flask(__name__) # 假设你的model已经提前加载完成 # model = ... @app.route('/pred_alphabet', methods=['POST']) def prediction(): audio_file = request.files.get('audio_file') if not audio_file: return jsonify({'code':400, 'message': '未上传音频文件'}) # 步骤1:将FileStorage保存为临时WAV文件 with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_wav: audio_file.save(temp_wav.name) temp_path = temp_wav.name try: # 步骤2:用pydub将音频转码为未压缩的PCM WAV audio = AudioSegment.from_file(temp_path, format='wav') # 导出为PCM编码的WAV(16位,单声道,16kHz采样率,适配Librosa常用配置) converted_temp_path = temp_path.replace('.wav', '_converted.wav') audio.set_frame_rate(16000).set_channels(1).set_sample_width(2).export(converted_temp_path, format='wav', codec='pcm_s16le') # 步骤3:用Librosa加载转码后的音频 y, sr = librosa.load(converted_temp_path, sr=16000) # 后续特征提取与预测逻辑保持不变 X = np.mean(librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40).T, axis=0) X = np.array(X) X = np.expand_dims(X, -1) predictions = model.predict(X) labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] predicted_labels = [labels[np.argmax(pred)] for pred in predictions] mode = statistics.mode(predicted_labels) return jsonify({'code':200, 'result': str(mode)}) finally: # 清理临时文件,避免磁盘占用 if os.path.exists(temp_path): os.remove(temp_path) if os.path.exists(converted_temp_path): os.remove(converted_temp_path) if __name__ == '__main__': app.run(debug=True)
关键细节说明
- 临时文件处理:Flask的
FileStorage对象不能直接传给Librosa,通过临时文件可以确保音频数据被正确写入磁盘后再处理 - 强制转码:
pcm_s16le是Librosa/Soundfile原生支持的未压缩编码,同时设置16kHz采样率、单声道,能统一输入格式,避免因Android录制参数差异导致的问题 - 资源清理:使用
finally块确保临时文件无论成功失败都会被删除,避免服务器磁盘占用
额外排查点
如果仍有问题,可以检查:
- 确认Android端录制的音频确实是WAV格式(部分设备可能实际是MP3但后缀标为WAV)
- 安装pydub依赖时确保已安装ffmpeg:
pip install pydub,并在系统环境变量中配置ffmpeg路径
内容的提问来源于stack exchange,提问作者Muhammad Rizki
相关产品推荐
相关产品推荐

