ONVIF 语音对讲实现流程

要实现语音对讲,我们需要:

  1. 使用携带特定Require头的RTSP协议与相机通讯,获取SDP文件,然后建立backchannel连接
  2. 采集电脑的音频
  3. 封装音频并通过网络发送给相机

RTSP 部分

参考ONVIF 文档使用特殊的Require头进行一系列请求之后我们就获得了完整SDP,这里重点显示backchannel的那部分:

m=audio 0 RTP/AVP 104
c=IN IP4 0.0.0.0
b=AS:50
a=sendonly
a=control:rtsp://192.168.10.147/trackID=4
a=rtpmap:104 mpeg4-generic/16000/1
a=fmtp:104 profile-level-id=15; streamtype=5; mode=AAC-hbr; config=1408;SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1;
a=Media_header:MEDIAINFO=494D4B48010200000400000101200110803E0000803E000000000000000000000000000000000000;
a=appversion:1.0

由上面可以看出,媒体类型audio,传输协议是RTP/AVP,RTP payload是104,属性sendonly表明只接收数据,控制流的urirtsp://192.168.10.147/trackID=4。属性rtpmaprtp payload是104,媒体格式为mpeg4-generic也就是aac,采样率为16000,通道数为1。知道这些信息之后我们就可以SETUP建立连接了。 发送SETUP rtsp://192.168.10.147/trackID=4请求,其中Transport设为RTP/AVP;unicast;client_port=1234-1235,请求与回复如下:

SETUP rtsp://192.168.10.147/trackID=4 RTSP/1.0
CSeq: 4
Session: 123124
Transport: RTP/AVP;unicast;client_port=1234-1235
Require: www.onvif.org/ver20/backchannel
RTSP/1.0 200 OK
CSeq: 4
Session: 123124;timeout=60
Transport:RTP/AVP;unicast;client_port=1234-1235;server_port=8372-8373

然后根据回复中的server_port=8372-8373可以得知服务端分别使用8372接受RTP,8373接受RTCP。 在完成PLAY请求之后我们就可以开始推送电脑采集的音频流了。

采集电脑的音频

要想推送电脑的音频流首先需要采集电脑的音频流,在gtreamerElementpulsesrc可以非常容易地获取到pulseaudio服务中的音频,例如:

  • 采集并播放音频:gst-launch-1.0 pulsesrc ! audioconvert ! autoaudiosink
  • 采集音频并编码成带adtsaac格式并保存文件:gst-launch-1.0 pulsesrc ! avenc_aac ! aacparse ! audio/mpeg,mpegversion=4,stream-format=adts ! filesink location=colletion.aac
    • acenc_aac 将采集的audio/x-raw编码成audio/mpeg,mpegversion=4,stream-format=raw
    • aacparse 将aacstream-format=raw转成stream-format=adts也就是添加了adts(Audio Data Transport Stream)
    • filesink 将数据保存成文件

封装成 RTP 并发送到相机

我们已经采集到音频流,最后只需要封装成RTP并通过udp发送到相机的UDP端口8372就行了,使用如下命令:

  • gst-launch-1.0 pulsesrc ! avenc_aac ! aacparse ! audio/mpeg,mpegversion=4,stream-format=adts ! rtpgstpay pt=104 ! udpsink host=192.168.10.147 port=8372 bind_port=1234
    • rtpgstpay 将带adts头的aac封装成rtp包,其中pt就是payload type用的是上面指定的104
    • udpsink 把rtp包使用udp协议从本机的1234端口发送到192.168.10.147:8372 这时候我们在电脑麦克上说话就可以在相机的音响上播放出来了。