文章目录
- 1. FreeSWITCH 检测 DTMF 的方式
- 1.1 RFC2833
- 使用方式
- 1.2 INBAND
- 使用方式
- 1.3 SIP INFO
- 使用方式
- 2. DTMF 数据重复问题
- 2.1 start_dtmf 的问题
- 2.3 运营商传输问题
1. FreeSWITCH 检测 DTMF 的方式
DTMF(Double Tone Multiple Frequency,双音多频)
本质上是由高频音和低频音的两个正弦波合成的音频信号,不过随着技术发展,已经引申指代为电话通话过程中按键信息传输的一种方式。在 SIP 通话中,传输按键信息的方法较多,大致分为以下三种
1.1 RFC2833
RFC2833
是 FreeSWITCH 默认开启的 DTMF 检测配置,这种方式实际是由 RTP 协议中特殊的 Payload Type(按照惯例值 101)
即 telepone-event 来标识 RFC2833 数据包,用最后一个 end 标志为 1 的 RFC2833 数据包表示 DTMF 传输结束,以文本形式直接传输按键值。一轮 DTMF 经常会多次按键输入多个数字,这样就会对应多个 RTP 数据包,在 RFC2833
模式下这些 RTP 包的时间戳相同,据此可以将多个按键值聚合作为一轮 DTMF 按键采集的最终值
在 FreeSWITCH 日志中,如果存在 RTP RECV DTMF 关键字,则按键值是通过 telepone-event 标识直接从 RTP 包中取出来的文本数据
使用方式
- 使用 play_and_get_digits APP,向 FreeSWITCH 下发采集按键的指令
- 通过 esl 订阅
CHANNEL_EXECUTE_COMPLETE
事件,在该事件监听的处理逻辑判断执行的 Application 为 play_and_get_digits,再从对应的变量中取得按键值
1.2 INBAND
INBAND
为带内检测方式,这种模式下按键值以音频信号表示,封装在 RTP 包中与普通的 RTP 语音包一起传输,检测的唯一方法是实时提取所有 RTP 包音频数据进行频谱分析,得到高频音和低频音的频率然后查表确认对应的按键值。由于 RTP 音频数据解码有一定的 CPU 消耗,不推荐使用这种方式
在 FreeSWITCH 日志中,如果存在 DTMF DETECTED 关键字,则按键值是使用带内检测从音频信号里分析出来的
使用方式
- 在需要使用的拨号计划中增加如下配置,需注意如果 start_dtmf 与 ring_ready 一起使用,需确保首先调用 ring_ready
<action application="set" data="dtmf_type=inband"/> <action name="start_dtmf"/>
- 通过 esl 订阅
DTMF
事件,在该事件监听的处理逻辑中拿到用户按键信息
1.3 SIP INFO
SIP INFO
为带外检测方式,直接通过 SIP 信令通道传输 DTMF 数据。这种方式比 RFC2833
更有效率,但由于 SIP 信令和 RTP 收发采用的是不同的端口,所以可能会造成收到 DTMF 和实际的声音不同步的问题
如果媒体协商时 SDP 里没有 telepone-event 则表明 SIP 设备不支持
RFC2833
模式传输按键信息,此时 FreeSWITCH 会默认改用SIP INFO
模式传输 DTMF,产生如下日志:No 2833 in SDP. Disable 2833 dtmf and switch to INFO
使用方式
在需要使用的拨号计划中增加如下配置
<action application="set" data="dtmf_type=info"/>
2. DTMF 数据重复问题
2.1 start_dtmf 的问题
在使用 start_dtmf APP 采用带内检测的方式采集 DTMF 按键时,如果运营商同时用 INBAND
和 RFC2833
两种方式传输了 DTMF 信号,则在 FreeSWITCH 中会出现按键数据重复的问题,因为 FreeSWITCH 默认开启的 RFC2833
也会解析获取按键信息。这种情况有两种解决方法:
- 要求运营商只采用一种方式发送 DTMF
- 关闭 FreeSWITCH 的 INBAND 的检测方式,不使用 start_dtmf
2.3 运营商传输问题
在某些情况下,运营商确实存在重复传输 DTMF 信号的问题。这种情况需要使用 wireshark 抓包分析 RTP 流,导出音频流后使用相关工具分析频率,对照 DTMF 频率表确认是否存在重复发送问题,网上资料很多在此不做赘述