如何将蓝牙音频作为麦克风输入供给Android SpeechRecognizer完成语音识别
可行实现方案
首先明确答案:可以实现,无需依赖RecognizerIntent的默认采集逻辑,直接使用SpeechRecognizer底层API配合两种方案即可满足需求。
方案1:系统级音频路由切换(实现成本最低)
安卓系统本身支持将蓝牙SCO链路的音频设为默认语音输入源,仅需在调用识别接口前修改系统音频路由配置即可:
- 前置要求:首先申请必要权限
- 基础权限:
android.permission.RECORD_AUDIO、android.permission.MODIFY_AUDIO_SETTINGS - 蓝牙权限:安卓12及以上版本需额外申请
BLUETOOTH_CONNECT、BLUETOOTH_SCO动态权限
- 基础权限:
- 核心配置代码:
// 切换音频路由到蓝牙SCO通道 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); audioManager.startBluetoothSco(); audioManager.setBluetoothScoOn(true); // 正常初始化SpeechRecognizer启动识别即可,此时默认输入源为蓝牙SCO音频 SpeechRecognizer recognizer = SpeechRecognizer.createSpeechRecognizer(context); // 自行配置RecognitionListener回调处理识别结果 recognizer.startListening(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)); // 识别结束后恢复默认路由,避免影响其他应用 audioManager.setBluetoothScoOn(false); audioManager.stopBluetoothSco(); audioManager.setMode(AudioManager.MODE_NORMAL);
- 注意事项:树莓派端需要将降噪后的音频走蓝牙SCO通道传输,不要使用普通A2DP通道,A2DP为单向高质量音频输出通道,SCO才是安卓系统默认的语音输入通道。
方案2:自定义音频喂入(适配任意传输协议)
如果不想修改系统全局音频路由,或者你的音频是通过TCP/UDP等其他协议从树莓派传输到安卓,可直接将收到的音频流手动喂入SpeechRecognizer:
- 适用条件:原生安卓自带的Google识别服务从API 31开始支持自定义音频输入,第三方语音识别引擎多数也支持该能力
- 核心逻辑:
- 初始化
SpeechRecognizer并配置识别回调 - 启动识别时在Intent中指定和树莓派输出一致的音频参数(比如采样率16000、单声道、PCM16编码)
- 收到树莓派传输的PCM音频块后,直接通过识别器对应接口传入音频数据即可
- 初始化
- 注意事项:传入的音频格式必须和识别引擎要求的格式完全匹配,否则会出现识别准确率低、无返回结果等问题。
避坑提示
- 不要使用
RecognizerIntent封装的启动接口,该接口确实会强制调用设备自带麦克风采集逻辑,绕过它直接调用SpeechRecognizer原生API即可 - 蓝牙SCO连接建立有1~2秒的延迟,需要等
ACTION_SCO_AUDIO_STATE_UPDATED广播收到连接成功的回调后再启动识别,避免前几秒的音频丢失
内容的提问来源于stack exchange,提问作者GB-DEV
相关产品推荐
相关产品推荐

