VoIP通话之DTMF信号开发指南

一、前言

DTMF信号即双音频信号,最先用于程控电话交换系统来代替号盘脉冲信号,主叫用户摘机按键拨号后,电话号码所对应的DTMF信号通过电话线传到程控交换机中的DTMF接受电路,交换机中的微机识别被叫电话号码后,接通主被叫用户实现双方通话。

简单来说,DTMF信号就是在网络中传输话机按键拨号的数字。在可视对讲系统中,DTMF信号常用来控制门锁。

 

二、DTMF信号分类

目前传送DTMF信号有三种方式:

A.通过通信协议传输(SIP信令)

用SIP信令的INFO方法携带DTMF信号。

为带外检测方式,通过SIP信令的INFO方法携带DTMF信号。没有统一的实现标准,目前以Cisco SIPINFO为标准,通过SIPINFO包中的signal字段识别DTMF按键。注意当DTMF为“*”时不同的标准实现对应的signal=*或signal=10。SIPINFO的好处就是不影响RTP数据包的传输,但是因为SIP控制信令和媒体传输(RTP)是分开传输,很容易造成DTMF信号和媒体包不同步。

举个例子,在Voice Mail应用中,用户根据提示音输入一个DTMF信号,随后开始留言。Server是在接受到该DTMF信号后开始保存用户的留言。然而由于DTMF信号是通过SIP信令来传输的,而媒体流是通过RTP来传输的,有可能用户留言的RTP包先到,而该DTMF信号的INFO消息延迟,导致Server不保存用户的语音留言直至接受到INFO消息。

B. 通过RTP的数据内容传输(Inband)

为带内检测方式, In Band是指直接将DTMF的音频数字信号不经任何处理直接打成RTP包在IP网中传输。其中可能和用户的语音媒体流混合在一起传输。程序要获知哪个包有DTMF信号,是什么DTMF信号,必须提取RTP数据包进行频谱分析,经过频谱分析得到高频和低频的频率,然后查表得到对应的按键。在选择压缩比很高码率很低的codec,比如G.723.1和G.729A等。主要缺陷是由于网络丢包的影响,有时会造成DTMF信号丢失,而且DTMF音混合在语音包中,容易产生偏差,造成信号失真。

C. 通过rfc2833的规则和格式包传输

为带内检测方式,通过RTP传输,由特殊的rtpPayloadType即TeleponeEvent来标示RFC2833数据包。同一个DTMF按键通常会对应多个RTP包,这些RTP数据包的时间戳均相同,此可以作为识别同一个按键的判断依据,最后一包RTP数据包的end标志置1表示DTMF数据结束。另外,很多SIP UA 包括IAD都提供TeleponeEvent的设置功能如3CX Phone,Billion-IAD,ZTE-IAD等默认的TeleponeEvent都为101,但可以人为修改,这时要求在进行RFC2833 DTMF检测之前需事先获取SDP协商的TeleponeEvent参数。

 

三、SIP信令传输

sip信令传输方式即通过发送一条sip message给对方,对方需解析出body中的Signal字段。使用eXosip库时,可以通过eXosip_call_send_request函数发送sip message。下面是一个典型的sip info型dtmf信号:

INFO sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 10.6.120.251:5060;rport;branch=z9hG4bK1621627249
From: ;tag=1898662385
To: "102" ;tag=as71f3cca7
Call-ID: [email protected]:5060
CSeq: 3 INFO
Contact: 
Content-Type: application/dtmf-relay
Max-Forwards: 70
User-Agent: eXosip/3.6.0
Content-Length:    22

Signal=#
Duration=160

 

四、RFC2833传输

这种类型的dtmf信号存在于RTP音频流中,所以构建它相对不容易。我们先来看下DTMF信号RTP包的组成:

VoIP通话之DTMF信号开发指南_第1张图片

首先从RTP头开始分析:

Version(版本,2bit):此域定义了RTP的版本。此协议定义的版本是2

Padding(填充位,1bit):如果该位置位,则该RTP包的尾部就包含附件的填充字节;

Extension(扩展位,1bit):如果该位置位,RTP固定头部后面就跟有一个扩展头部;

Contributing source identifiers count(CSRC计数器,4bit):含有固定头部后面跟着的CSRC的数目;

Marker(标志,1bit):标志的解释由具体协议规定。rfc2833协议中,开始时该位要置1,结束时置0;

Payload type(负载类型, 7bit):标识了RTP传输的负载类型。传输DTMFF信号时,该位为101;

sequence number(序列号,16bit):每发送一个RTP数据包,序列号加1,接收端可以依次检测丢包和重建包序列。序列号的初始值是随机的;

timestamp(时间戳,32bit):记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成为一个初始值。即使在没有信号发送时,时间戳的数值也要随着时间而不断的增加。时间戳是去抖动和实现同步不可缺少的数据。

Synchronization Source identifier(同步源标识符,32bit):同步源是指RTP包的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的,RFC1889推荐了MD5随机算法。

再来看RFC2833信号:

Event ID(按键编号,8bit):表示按下的按键编号

End of Event(结束标志位,1bit):如果该位置位,则表示DTMF信号结束;

Reserved(预留位,1bit):未定义;

Volume(音频音量,6bit):表示该音频的音量大小;

Event Duration(事件持续时长,16bit):表示按键按下事件持续的时长。

分析完RTP包每个字节的意义后,我们就可以按照协议规则进行组包了。一般一个按键事件会连续发送4个RTP包,每个包的序列号、时间戳、持续时长都会不一样。最后将代表结束的一个RTP包连续发送三次。

你可能感兴趣的:(流媒体开发之路,voip)