如何在Android设备上使用Python获取麦克风音频输入
安卓平台Kivy+SpeechRecognition获取麦克风输入可行方案
核心前提配置
90%的音频采集失败都是配置漏项导致的,不管用哪种采集方案先把基础配置改对:
- 修改
buildozer.spec打包配置文件:- 在
requirements项添加依赖:python3, kivy, speechrecognition, plyer, pyjnius - 在
android.permissions项添加录音权限:RECORD_AUDIO - 将
android.minapi设为21,android.api设为33,适配绝大多数在售安卓设备
- 在
- 代码启动时先动态申请录音权限(安卓6.0以上危险权限不能仅靠Manifest静态声明):
from plyer import permission # 用户授权完成后再执行录音逻辑 permission.request_permission("android.permission.RECORD_AUDIO")
注:PyAudio不兼容安卓的核心原因是其依赖的PortAudio库没有适配安卓音频驱动的官方编译版本,不用反复尝试打包PyAudio,必然报错。
方案1:通过PyJNIus调用安卓原生AudioRecord(最稳定,无额外依赖)
直接调用安卓系统自带的音频采集API,不存在兼容问题,只需要封装成SpeechRecognition支持的音频源格式即可:
- 封装原生音频采集类,输出SpeechRecognition要求的16kHz、16位、单声道PCM格式数据
- 将封装好的类作为自定义音频源传入SpeechRecognition的识别逻辑
核心代码示例:
from jnius import autoclass import speech_recognition as sr from threading import Thread # 导入安卓原生类 AudioRecord = autoclass("android.media.AudioRecord") MediaRecorder = autoclass("android.media.MediaRecorder$AudioSource") AudioFormat = autoclass("android.media.AudioFormat") class AndroidMicrophone: def __init__(self, sample_rate=16000, chunk_size=1024): self.sample_rate = sample_rate self.chunk_size = chunk_size self.channel_config = AudioFormat.CHANNEL_IN_MONO self.audio_format = AudioFormat.ENCODING_PCM_16BIT self.buffer_size = AudioRecord.getMinBufferSize( sample_rate, self.channel_config, self.audio_format ) self.recorder = None def __enter__(self): self.recorder = AudioRecord( MediaRecorder.MIC, self.sample_rate, self.channel_config, self.audio_format, max(self.buffer_size, self.chunk_size*2) ) self.recorder.startRecording() return self def __exit__(self, exc_type, exc_val, exc_tb): if self.recorder: self.recorder.stop() self.recorder.release() def read(self, size=None): read_size = size if size else self.chunk_size buf = bytearray(read_size*2) self.recorder.read(buf, 0, len(buf)) return bytes(buf) # 调用示例 def recognize_speech(): r = sr.Recognizer() with AndroidMicrophone() as source: r.adjust_for_ambient_noise(source) audio = r.listen(source) try: result = r.recognize_google(audio, language="zh-CN") print("识别结果:", result) except Exception as e: print("识别失败:", e) # 注意:录音和识别逻辑必须放在子线程运行,不能阻塞Kivy主线程 Thread(target=recognize_speech, daemon=True).start()
方案2:Audiostream失效常见修复点
如果之前用Audiostream无法采集,对照以下项排查即可,不需要额外换库:
- 确认
buildozer.spec的requirements里明确添加了audiostream依赖 - 初始化Audiostream时音频参数必须匹配安卓硬件支持范围:采样率选16000Hz/44100Hz,单声道,16位PCM格式,参数不匹配会直接初始化失败
- 必须在用户动态授权录音权限之后再初始化Audiostream,提前初始化会因为权限不足返回空数据
- Audiostream默认采集的是44100Hz采样率数据,需要重采样转成16000Hz再传给SpeechRecognition,否则识别准确率会极低。
注意事项
- 所有音频采集、语音识别逻辑不能放在Kivy的主UI线程运行,否则会触发应用无响应(ANR)报错
- 安卓10以上系统如果要保存录音文件,需要额外申请对应存储权限
- 测试必须用真机,安卓模拟器的麦克风驱动普遍存在兼容问题,不能作为功能是否正常的判断依据
内容的提问来源于stack exchange,提问作者DXNI
相关产品推荐
相关产品推荐

