主要需要实现如下几个核心能力:
1、支持GB28181的SIP协议栈;
2、网络框架,处理UDP、TCP等Socket;
3、H264/H265/AAC/OPUS/等编码和解码库;
4、解码播放显示框架;
主要三方框架:
1、网络框架使用ZLMediaKit中的zltoolkit ;
2、sip协议栈使用sip_sofia ;
3、codec包括ffmpeg/x264/openh264, ilbc,faac,faad2,opus ;
4、解码播放显示框架使用anyrtc-rtmp的播放框架;
框架结构如下图:
anyrtc-rtmp | ||
---|---|---|
SipClient | SdpParser | |
sip_sofia | zltoolkit | audiocodec/videocodec(ffmpeg x264 openh264 ilbc,faac,faad2,opus) |
业务流程:
0、在拉流的输入框输入设备的sip地址,如sip:4879998989898998@192.168.20.10:5060, 修改AnyRtmplayerImpl::OnMessage的方法,处理sip输入:
// sip:4879998989898998@192.168.20.10:5060
if (str_url_.find("sip") != std::string::npos) {
SipClient::Inst().start(str_url_, this);
return;
}
1、使用sip_sofia客户端接口注册到SIP服务器上,主要参考:http://sofia-sip.sourceforge.net/refdocs/nua/ 实现一个sip客户端,这里封装的对象为SipClient;
2、需要注意的是,注册时携带了rport参数,用来要求服务器返回当前设备的NAT地址,并保存该IP,用来作为SDP报文中的本地客户端地址,由于是测试,并没有开启鉴权,也就是收到403请求后,需要重新发送Register请求;
3、注册完成后,呼叫对应的设备,既发出invite请求,并等到200 OK,解析SDP报文,提取对方发送的IP和端口,由于只是查看监控流,所以客户端并不会给服务器返回的IP、端口发送数据包,为了解决NAT问题,客户端需要启动一个NAT线程,定时给对方端口发送空包,以保证NAT端口的保活;
4、在呼叫请求中,监听本端生成的IP和端口,接收监控的数据流;
5、接收到RTP数据流后,交给对应的回调方法,处理流的解码和显示,这里主要使用anyrtc-rtmp的框架,并没有过多的修改,需要关注音视频的同步,卡顿现象,做一些优化;