Python 实现手机通话语音通过 UDP 传输至局域网
前言
此前我们探讨过在 Android 手机上拦截通话声音并插播语音片段,或者根据 DTMF 按键播放 IVR 应答的方案。但在 AI 电话沟通场景中,受限于手机本身的算力和性能,大模型通常无法直接部署在终端设备上。这就需要将拦截到的通话音频数据,通过网络(局域网或互联网)传输给具备 AI 算力的服务器。
由服务器对语音进行 ASR 识别和语义理解,生成应答 TTS 语音后,再反馈回手机注入到通话流中。
目前实时语音流的传输方式主要有两种:
- SIP/WebRTC 协议及配套的 RTP/RTCP 数据传输。
- 直接将语音数据以 UDP 广播或组播的方式分发给局域网内设备。
虽然我们在 SIP 协议对接 FreeSwitch、VOS 及呼叫中心方面投入了大量精力,但本质上,手机电话做 AI 呼叫并不强依赖 SIP 协议。手机 APP 提取到通话声音后,完全可以直接传给局域网内的 AI 服务器,或者让本地 AI 模型消费会话。相比 SIP,这种方式更灵活,例如处理'拨号带逗号自动转分机'这类逻辑时就没有协议限制。
本文基于上述场景,介绍如何部署一台局域网 AI 服务器,通过 UDP 数据包同时处理多台 Android 手机的 AI 呼叫请求,并生成 TTS 应答。由于交互全在局域网内进行,端到端时延极低(TTL 仅 1-2 跳),既能利用服务器的算力密度,又能高效响应多路 SIM 卡通话,实现低成本 AI 呼叫。
方案依赖配件
目前拦截手机通话声音的主流方案是蓝牙电话方案。这需要借助一个外置的 USB 蓝牙适配器插入手机,APP 才能拦截到通话事件和声音数据。
该方案优势在于普适性强,市面上任何品牌型号的 Android 手机,只要插上配件并安装 APP,即可支持。适配器的形态通常类似下图所示:
![USB 蓝牙适配器示意图]
购买到的 USB 蓝牙配件通常是标准接口,Android 手机可能需要一个 USB 转 Type-C 的转接头才能连接,这个配件很便宜,电商平台均可购得。
方案配置界面
为了让手机 APP 将语音数据和通话事件发布到局域网,需要对【智能拨号器 App】进行基础设置。进入 APP 设置选项卡,点击右上角齿轮图标打开【APP 应用设置】界面。
关键步骤是将默认的'SIP 协议栈:连接 SIP 平台'切换为'协议栈:手机 IVR-AI 语音处理'。
完成此设置后,APP 拦截到的通话声音不再转发至 SIP 平台,而是直接在手机与局域网内寻址到的【远程声音设备】之间进行数据交换。
Python 客户端命令行操作
本方案的 Python 脚本作为【远程声音设备】的标准输入输出源文件,支持 Windows、Linux 和 MacOS 三大平台(Windows 11 和 Ubuntu 18.04 已验证可用)。
详细的安装和配置步骤建议参考源码包中的 README.md 文档。简要来说,执行以下命令后即可启动服务:
pip install sounddevice numpy colorama
python main.py
运行后输入 help 或直接回车,会显示可用的命令行指令列表。主要流程如下:
- 发现设备:输入
discover扫描局域网内的手机设备。 - 绑定设备:输入
bind <设备 GUID>进行绑定。此时手机 APP 上会弹出提示框,需确认允许远程声音设备接入。 - 控制通话:绑定成功后,可使用以下指令进行通话控制:
call 10086:拨打指定号码。dtmf 2:通话中发送数字键。hangup:挂断电话。
程序架构设计
有了源代码后,具体的架构细节其实一目了然,核心代码仅六七个 Python 文件,简洁易懂。不过为了便于理解,这里梳理一下整体逻辑。
Python 脚本作为远程声音设备,采用 UDP + TCP 混合模式工作:
- UDP 协议:负责广播找人、寻址和绑定目标设备,以及电话通话期间上行和下行的全双工语音数据传输。占用端口范围 42700-42703。
- TCP 协议:负责建立稳定连接,确保通话事件和状态信息准时、完整地交换。电脑端使用随机端口,手机端固定使用 42700 端口。


