监听模式 spy 使用说明
spy 模式用于旁路监听 FreeSWITCH 通话音频,并把音频实时推送给 EasyMrcp 做 ASR 识别。
普通通话模式下,EasyMrcp 通过 SIP/SDP 协商拿到 RTP 音频;spy 模式下,EasyMrcp 不参与被监听通话的 SIP 协商,而是先给客户端分配一个 ASR RTP 接收端口,再由 FreeSWITCH 的 mod_easymrcp_spy 模块把通话音频推过来。
1. 适用场景
spy 模式适合这些场景:
- 对已有通话做旁路实时转写。
- 呼叫双方仍按原有业务流程通话,EasyMrcp 只负责识别音频。
- 需要同时监听 A-leg、B-leg,或者只监听其中一路。
- 不希望改造原有 SIP 媒体协商链路。
如果业务本身就是让机器人和用户对话,优先使用普通 EasyMrcp 通话模式;如果业务是“已有通话旁边再挂一条识别链路”,再使用 spy。
2. 整体流程
业务脚本
├─ 连接 EasyMrcp TCP 端口
├─ 发送 ClientConnect,data={"Type":"spy"}
├─ 等待 EasyMrcp 返回 rtpPort
├─ 调用 FreeSWITCH 命令 easymrcp_spy_start <EasyMrcpIP>:<rtpPort>
└─ 发送 DetectSpeech 开始识别
FreeSWITCH mod_easymrcp_spy
└─ 把当前通话音频编码为 G.711A RTP,推给 EasyMrcp
EasyMrcp
├─ 接收 RTP
├─ 按当前 ASR 配置识别
└─ 返回 RecognitionComplete / NoInputTimeout 等事件源码里 ClientConnectEventHandler 对 Type=spy 做了特殊处理:创建 ASR 处理器、分配 ASR RTP 端口,并通过 ClientConnect 事件把 rtpPort 返回给客户端。
3. 编译安装 FreeSWITCH 模块
模块示例位于:
examples/mod_easymrcp_spy/编译:
cd /path/to/EasyMrcp/examples/mod_easymrcp_spy
make安装:
sudo make install加载模块:
load mod_easymrcp_spy也可以加入 FreeSWITCH 的 modules.conf.xml:
<load module="mod_easymrcp_spy"/>4. FreeSWITCH 命令
启动监听:
easymrcp_spy_start <target_ip>:<target_port>停止监听:
easymrcp_spy_stop其中:
| 参数 | 说明 |
|---|---|
target_ip | EasyMrcp 服务地址。 |
target_port | EasyMrcp 返回的 rtpPort。 |
示例:
easymrcp_spy_start 192.168.1.100:20000这个命令必须在某一路 FreeSWITCH session 里执行,不能脱离通话上下文单独执行。
5. TCP 连接参数
客户端连接 EasyMrcp 时,ClientConnect 的 data 里需要传入:
{
"Type": "spy"
}EasyMrcp 返回:
{
"rtpPort": 20000
}拿到 rtpPort 后,再调用:
easymrcp_spy_start <EasyMrcpIP>:<rtpPort>随后按普通 ASR 流程发送 DetectSpeech:
{
"StartInputTimers": false,
"NoInputTimeout": 60000,
"SpeechCompleteTimeout": 800,
"AutomaticInterruption": true
}spy 模式下源码会强制把 PushAsrRealtimeResult 设为 false。如果需要实时中间结果,建议先确认业务是否能接受监听链路和普通对话链路的事件语义差异。
6. Python 示例脚本
示例脚本位于:
examples/mod_easymrcp_spy/spy_handler.py核心逻辑是:
- 用当前通话 UUID 创建
EasyMrcpTcpClient。 - 注册
ClientConnect、RecognitionComplete、NoInputTimeout回调。 - 发送
ClientConnect,参数为{"Type":"spy"}。 - 从返回数据里取出
rtpPort。 - 执行
session.execute("easymrcp_spy_start", "<EasyMrcpIP>:<rtpPort>")。 - 发送
DetectSpeech开始识别。 - 通话结束时关闭 TCP 连接,并停止监听。
如果需要同时监听 A-leg 和 B-leg,可以为两路通话分别创建 TCP 客户端和 spy 推流。
7. 注意事项
mod_easymrcp_spy输出的是 G.711A RTP,EasyMrcp 侧按mediaType=8接收。- EasyMrcp 返回的
rtpPort来自 ASR RTP 端口池,要确保防火墙已放通 UDP。 ClientConnect必须先完成,拿到rtpPort后才能启动easymrcp_spy_start。- 如果没有识别结果,优先检查 FreeSWITCH 到 EasyMrcp 的 UDP 连通性。
- 监听模式不会自动桥接或控制原通话,桥接、挂断、双路监听都由业务脚本负责。
- 通话结束时要停止监听并关闭 TCP 客户端,避免 RTP 端口和会话资源残留。
8. 常见问题
| 现象 | 排查方向 |
|---|---|
ClientConnect 没有返回 rtpPort | 检查 data 是否为 {"Type":"spy"},以及 EasyMrcp ASR RTP 端口池是否可用。 |
| FreeSWITCH 命令执行失败 | 确认 mod_easymrcp_spy 已加载,并且命令在通话 session 中执行。 |
| 能连接但没有识别结果 | 检查 UDP 是否放通,easymrcp_spy_start 的 IP/端口是否使用 EasyMrcp 返回值。 |
| 识别结果延迟明显 | 检查网络抖动、ASR 模式、VAD 参数和 SpeechCompleteTimeout。 |
| 多路监听串音 | 每路监听必须使用独立 TCP client id 和独立返回的 rtpPort。 |
