通过蓝牙注入音频文件到麦克风流 实现语音识别自动化测试
解决方案:基于Bumble扩展HFP音频传输功能
要实现通过伪装HFP耳机发送音频文件给第三方VR设备,核心是在Bumble的HFP示例基础上,补充SCO链路的音频流发送逻辑,以下是具体步骤:
1. 明确HFP音频传输要求
HFP的语音传输依赖SCO同步链路,要求音频必须是:8kHz采样率、单声道、16位线性PCM格式。所有音频文件必须先转换成该格式,否则设备无法识别。
2. 修改Bumble的HFP Handsfree脚本
原run_hfp_handsfree.py仅处理AT命令交互,未实现SCO音频发送,需添加以下关键代码:
步骤2.1 导入音频处理依赖
在脚本顶部添加:
import wave import asyncio
步骤2.2 实现音频发送异步函数
添加专门的音频发送任务,按HFP帧间隔推送PCM数据:
async def send_audio(sco_socket, audio_path): # 验证音频格式是否符合要求 with wave.open(audio_path, 'rb') as audio_file: if (audio_file.getframerate() != 8000 or audio_file.getnchannels() != 1 or audio_file.getsampwidth() != 2): raise ValueError("音频必须是8kHz单声道16位PCM格式") # HFP SCO每帧对应20ms音频(160个采样点) chunk_size = 160 while True: chunk = audio_file.readframes(chunk_size) if not chunk: break await sco_socket.send(chunk) await asyncio.sleep(0.02) # 严格匹配20ms帧间隔
步骤2.3 连接后触发音频发送
找到脚本中处理HFP连接事件的部分,在连接建立后启动音频发送任务:
# 替换原有的连接回调逻辑 async def on_hfp_connected(client): print("HFP连接已建立,开始发送音频...") # 获取已建立的SCO套接字 sco_link = client.sco_socket if sco_link: # 启动异步音频发送任务 asyncio.create_task(send_audio(sco_link, "/path/to/your/test_audio.wav"))
3. 预处理测试音频文件
如果你的原始音频不符合HFP格式,用ffmpeg转换:
ffmpeg -i original_audio.mp3 -ar 8000 -ac 1 -c:a pcm_s16le test_audio.wav
4. 测试流程验证
- 运行修改后的脚本,等待第三方VR设备蓝牙连接到伪装的HFP耳机
- 设备连接成功后,脚本自动开始发送音频文件
- 检查VR设备是否将接收到的音频识别为对应命令
常见问题排查
- SCO链路未建立:确认第三方设备支持HFP 1.6及以上版本,且连接时已启用音频服务
- 音频识别失败:检查音频格式是否严格匹配,可直接用专业音频工具(如Audacity)导出符合要求的PCM文件
- 音频卡顿/断流:确保异步发送的帧间隔准确,避免主线程被其他任务阻塞
内容的提问来源于stack exchange,提问作者Kevin Zhao
相关产品推荐
相关产品推荐

