目前只测试了与大华摄像机的语音对讲功能,在此记录下对接工程中遇到的问题和收获。
首先我们需要理清下思路:
第一步要熟悉语音对讲的协议流程,下图为国标28181中的参考图:
这里我们可以简化下流程,只参与与摄像机的信令交互,也就是1,2,3,4,5,14,15 17,18
这里我将信令详情展示出来,以供参考
1.发送语音广播请求
MESSAGE sip:34020000001320000001@192.168.1.108:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.20:9088;branch=4dae6d98892f4a0fb630b8e77d49bc30;rport
To: "" <sip:34020000001320000001@4401020048>
From: "34020000002000000002" <sip:34020000002000000002@192.168.1.20:9088>;tag=6606061
Call-ID: 6b135a147f4b425e981406bdd9751924@192.168.1.20
CSeq: 1 MESSAGE
Max-Forwards: 70
Content-Length: 193
Content-Type: Application/MANSCDP+xml<?xml version="1.0" encoding="GB2312"?>
<Query>
<CmdType>Broadcast</CmdType>
<SN>991225</SN>
<SourceID>34020000002000000002</SourceID>
<TargetID>34020000001370000001</TargetID>
</Query>
2.设备回复OK
SIP/2.0 200 OK
Call-ID: 6b135a147f4b425e981406bdd9751924@192.168.1.20
Content-Length: 0
CSeq: 1 MESSAGE
From: "34020000002000000002"<sip:34020000002000000002@192.168.1.20:9088>;tag=6606061
To: ""<sip:34020000001320000001@4401020048>;tag=fcf251b2e36ab8324e6c7772c971ea06
User-Agent: SIP UAS V3.0.0.828177
Via: SIP/2.0/UDP 192.168.1.20:9088;rport=9088;branch=4dae6d98892f4a0fb630b8e77d49bc30
3.设备发送广播通知结果请求
MESSAGE sip:34020000002000000002@192.168.1.20:9088 SIP/2.0
Call-ID: 67c4f0acd67bb28284401481f6d66ba7
Content-Length: 187
Content-Type: Application/MANSCDP+xml
CSeq: 4997 MESSAGE
From: <sip:34020000001320000001@192.168.1.108:5060>;tag=8c22c278382c2ab79017a91f806b9ff0
Max-Forwards: 70
To: <sip:34020000002000000002@192.168.1.20:9088>
User-Agent: SIP UAS V3.0.0.828177
Via: SIP/2.0/UDP 192.168.1.108:5060;rport;branch=z9hG4bKa1bc3d6ca30b7e643b67aa393c7fb9f6<?xml version="1.0" encoding="GB2312" ?>
<Response>
<CmdType>Broadcast</CmdType>
<SN>991225</SN>
<DeviceID>34020000001370000001</DeviceID>
<Result>OK</Result>
</Response>
4.回复设备OK
SIP/2.0 200 Ok
Via: SIP/2.0/UDP 192.168.1.108:5060;rport=5060;branch=z9hG4bKa1bc3d6ca30b7e643b67aa393c7fb9f6;received=192.168.1.108
To: <sip:34020000002000000002@192.168.1.20:9088>
From: <sip:34020000001320000001@192.168.1.108:5060>;tag=8c22c278382c2ab79017a91f806b9ff0
Call-ID: 67c4f0acd67bb28284401481f6d66ba7
CSeq: 4997 MESSAGE
Allow: ACK, BYE, CANCEL, INFO, INVITE, NOTIFY, OPTIONS, PRACK, REFER, REGISTER, SUBSCRIBE
Content-Length: 0
5.设备主动发起INVITE 请求
INVITE sip:34020000002000000002@192.168.1.20:9088 SIP/2.0
Call-ID: 24174d55333b5ba8c1b04ea8be4a755f
Contact: <sip:34020000001320000001@192.168.1.108:5060>
Content-Length: 240
Content-Type: application/sdp
CSeq: 1 INVITE
Expires: 120
From: <sip:34020000001320000001@192.168.1.108:5060>;tag=a2752e81ddc7ca8693c411f8b3c77329
Max-Forwards: 70
Subject: 34020000002000000002:03d7a8ef3276a8ef327,34020000001370000001:0552354c54f3354c54f
To: <sip:34020000002000000002@192.168.1.20:9088>
User-Agent: SIP UAS V3.0.0.828177
Via: SIP/2.0/UDP 192.168.1.108:5060;rport;branch=z9hG4bK17794d3a5b5e56a894332fd42136c92fv=0
o=34020000001320000001 0 0 IN IP4 192.168.1.108
s=Play
i=VCam BroadCast Session
c=IN IP4 192.168.1.108
t=0 0
m=audio 9920 RTP/AVP 8 96
a=recvonly
a=rtpmap:8 PCMA/8000/1
a=rtpmap:96 PS/90000
y=0232409800
f=v/0/0/0/0/0a/1/8/1
14.回复给设备带SDP的OK确认消息
SIP/2.0 200 Ok
Via: SIP/2.0/UDP 192.168.1.108:5060;branch=z9hG4bK17794d3a5b5e56a894332fd42136c92f;rport
To: "" <sip:34020000002000000002@192.168.1.20:9088>;tag=24174d55333b5ba8c1b04ea8be4a755f
From: <sip:34020000001320000001@192.168.1.108:5060>;tag=a2752e81ddc7ca8693c411f8b3c77329
Call-ID: 24174d55333b5ba8c1b04ea8be4a755f
CSeq: 1 INVITE
Contact: "" <sip:34020000002000000002@192.168.1.20:9088>
Max-Forwards: 70
Content-Length: 169
Content-Type: APPLICATION/SDPv=0
o=34020000002000000002 0 0 IN IP4 192.168.1.20
s=Play
c=IN IP4 192.168.1.20
t=0 0
m=audio 30050 RTP/AVP 8
a=sendonly
a=rtpmap:8 PCMA/8000/1
y=0232409800
15.设备回复ACK确认消息
ACK sip:34020000002000000002@192.168.1.20:9088 SIP/2.0
Call-ID: 24174d55333b5ba8c1b04ea8be4a755f
Contact: <sip:34020000001320000001@192.168.1.108:5060>
Content-Length: 0
CSeq: 1 ACK
From: <sip:34020000001320000001@192.168.1.108:5060>;tag=a2752e81ddc7ca8693c411f8b3c77329
Max-Forwards: 70
To: <sip:34020000002000000002@192.168.1.20:9088>;tag=24174d55333b5ba8c1b04ea8be4a755f
User-Agent: SIP UAS V3.0.0.828177
Via: SIP/2.0/UDP 192.168.1.108:5060;rport;branch=z9hG4bK0571dff2cc66262a140a3a66925ca316
在这个过程中,我们可以得到以下信息:
1.设备支持8000采样率,单通道的PCMA流和90000 PS包
2.设备提供的收留端口为9920
3.我们发送流的端口为30050
4.我们需要发送的音频流为PCMA 8000采样率的RTP包
这里还有几点需要注意:
1.经过测试,语音对讲请求与设备的通道ID中是否标记为137无关,在信令1中TargetID字段的标红部分
2.发起语音广播请求1中,TargetID可以为设备ID,也可以为设备的通道ID,
3.设备发送的INVITE后,回复带SDP的OK响应时(信令14),to字段中tag不能为空,可以指定为call-id,否则无法收到ACK确认消息
4.回复带SDP的OK响应时(信令14),sdp协议中不要包含多余信息。如
m=audio 30050 RTP/AVP 8 96
a=sendonly
a=rtpmap:8 PCMA/8000/1
这里我们并没有使用96 PS流,如果这样发送过去,会导致设备确认后,立马发送BYE消息
所以,不必要的信息,最好不带,以免参数异常问题
至此,我们与摄像机建立了语音对讲的连接。接下来我们只需要使用协商好的端口往摄像机指定的端口发送数据流即可。
接下来,我们需要发送PCMA 8000的RTP包,这里需要用到VLC,ffmpeg,ffprobe,ffplay等工具,这些工具可以帮助我们测试。
首先,如何构建出一个PCMA 8000 单通道的问题,使用FFMPEG命令:
ffmpeg -i D:\CloudMusic\外婆.mp3 -map_metadata -1 -fflags +bitexact -acodec pcm_alaw -ac 1 -ar 8000 外婆_PCMA.wav -y
参数详解: -acode pcm_alaw 编码为pcma格式
-ac 1 单声道
-ar 8000是采样率8000
-map_metadata -1 -fflags +bitexact 是将ffmpeg转码默认携带的LIST的数据(artist,genre等)去掉,变成标准的44字节的wav文件头
这里使用fprobe工具查看我们转码的文件是不是我们想要的
ffprobe C:\Users\24610\外婆_PCMA.wav
这里,我们看到的确是我们想要的文件,那么如何打包成RTP流发送出去呢?
我们打开VLC,
这里我们已经开始发送RTP流了,我们可以使用ffplay播放,
ffplay -i rtp://192.168.1.20:5004
或者再启动一个VLC,打开网络串流输入:rtp://192.168.1.20:5004 都是可以的,这里我们可以拿来测试RTP包是否发送正常,这里还不能往摄像机发送,因为这里发送端口是随机的,我们需要使用特定端口(这里是30050)来发送,这就要在代码中实现的。