基于ZLMediaKit的GB28181视频平台demo

GB28181

主要内容
  • 国标的20位id是按照标准来定的,前8位是地域信息,9-10位是行业信息,11-13是设备类型、14是网络标识、后6位为序号

  • 约定以SIP协议作为会话通道的使用标准,以RTP作为语言和视频的载体。联网系统在进行音视频传输及控制时需要建立两个通道:会话通道(传输信令)和流媒体通道

协议架构:

基于ZLMediaKit的GB28181视频平台demo_第1张图片

注册

注册过程:

1. SIP代理向SIP服务器发送Register请求;
2. SIP服务器向SIP代理发送响应401,并在响应的消息头WWW_Authenticate字段中给出适合SIP代理的认证体制和参数;
3. SIP代理重新向SIP服务器发送REGISTER请求, 在请求的Authorization字段给出信任书,包含认证信息;
4. SIP服务器对请求进行验证,如果检查出SIP代理身份合法,向SIP代理发送成功响应200OK,如果身份不合法则发送拒绝服务应答。

参数解读:

REGISTER sip:34020000002000000001@3402000000 SIP/2.0
Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1371463273
From: sip:34020000001320000003@3402000000;tag=2043466181
To: sip:34020000001320000003@3402000000
Call-ID: 1011047669
CSeq: 1 REGISTER
Contact: sip:[email protected]:5060
Max-Forwards: 70
User-Agent: IP Camera
Expires: 3600
Content-Length: 0
​
=================
​
第1行表明这条SIP消息的方法(Method)是REGISTER,34020000002000000001是SIP服务器的国标ID,国标ID指的是由中心编码(8位) 、行业编码(2位) 、类型编码(3位)和序号(7位)四个码段共20位十进制数字字符构成,具体国标ID的编码方法可以参考GB/T 28181—2016中的附录D。3402000000指的是SIP服务器的域国标ID,SIP/2.0指的是SIP协议版本。
​
第2行为Via头,Via头中包含了发送请求方的相关信息,后续需要使用这些信息进行回复。SIP/2.0/UDP表示使用的是2.0版本的SIP协议,使用的传输协议是UDP,也可以使用TCP协议。192.168.137.11:5060为请求发送方的IP地址和端口号。Via头中必须包含branch参数,具体值是一个在整个SIP通信过程中不重复的数值。branch是一个事务ID(Transaction ID),用于区分同一个UA所发起的不同Transaction,它不会对未来的request或者是response造成影响,对于遵循IETF RFC3261规范的实现,这个branch参数的值必须用”z9hG4bK”打头. 其它部分是对To, From, Call-ID头域和Request-URI按一定的算法加密后得到。rport字段表示使用rport机制路由响应,即发送的响应时,按照rport中的端口发送SIP响应,也就是说IP和端口均完全遵照从哪里来的,发回哪里去的原则,如果没有rport字段时,服务端的策略是IP使用UDP包中的地址,即从哪里来回哪里去,但是端口使用的是via中的端口,详情见IETF RFC35818。  
​
第3行为From头,From头中包含了请求发送方的逻辑标识,在GB28181协议中是发送请求的设备国标ID和域国标ID信息。tag参数是为了身份认证的,值为随机数字字符。  
第4行为To头,To头在SIP协议中是为了标明请求接收方的逻辑标识的,在GB28181协议中填写的是发送请求的设备国标ID和域国标ID信息。  
第5行为Call-ID头,Call-ID头是全局唯一的,在同一个session中保持一致,在不同session中不同。  
第6行为CSeq头,CSeq头又叫Command Seqence(命令队列),用于标识命令顺序,值为序号+Method,序号部分为无符号整数,最大值为2^31。序号起始值是随机的,后续在同一个session中依次递增,比如发1 REGISTER没返回--->再发2 REGISTER--->没返回--->再发3 REGISTER--->这时返回了2 REGISTER就知道是第2个请求得到了响应。对于ACK和CANCLE中的CSeq与INVITE中的Cseq保持一致。  
第7行为Contact头,Contact头包含源的URI信息,用来给响应消息直接和源建立连接用。在GB28181协议中为SIP设备编码@源IP地址端口。  
第8行为Max-Forwards头,Max-Forwards头用于设置包最大中转次数,默认是70。  
第9行为User-Agent头,User-Agent头用于设置关于UA的信息,用户可以自定义。  
第10行为Expires头,Expires头表示超时时间。  
第11行为Content-Length头,Content-Length头表示SDP消息的长度,因为REGISTER消息不需要SDP,因此为0。         
                                        
保活

当UA发现工作异常时, 应立即向本SIP监控域的SIP服务器发送状态信息; 无异常时,应定时向本SIP监控域的SIP服务器发送状态信息。

基于ZLMediaKit的GB28181视频平台demo_第2张图片

SIP协议

SIP(Session Initiation Protocol,会话初始协议)是由IETF(Internet Engineering Task Force,因特网工程任务组)制定的多媒体通信协议。

会话模式

SIP协议有两种会话模式:会话中消息体内容大于1300字节时采用session mode,不大于时采用pager mode

消息体

SIP的消息体结构与HTTP协议结构十分相似:

  • 请求行or状态行

    • 请求行格式:Method Request-URI SIP-Version CRLF,举例:INVITE sip:[email protected] SIP/2.0 /r/n

  • 消息体

  • body

请求方法
  • REGISTER:注册联系信息

  • INVITE:发起会话请求

  • ACK:INVITE请求的响应的确认

  • CANCEL:取消请求

  • BYE:终止会话

  • OPTIONS:查询服务器能力

  • MESSAGE:传递不超过1300字节的数据

状态码
状态码 msg 含义
100 Trying 试呼叫
180 Ringing 振铃
181 Call is Being Forwarded 呼叫正在前转
200 OK 成功响应
302 Moved Temporarily 临时迁移
400 Bad Request 错误请求
401 Unauthorized 未授权
403 Forbidden 禁止
404 Not Found 用户不存在
408 Request Timeout 请求超时
480 Temporarily Unavailable 暂时无人接听
486 Busy Here 线路忙
504 Server Time-out 服务器超时
600 Busy Everywhere 全忙
SDP协议
内容

SDP是会话描述协议的缩写,是描述流媒体初始化参数的格式,由IETF作为RFC 4566颁布。流媒体是指在传输过程中看到或听到的内容

SDP通常包括如下信息:

  • 会话信息

    • 会话名和目的

    • 会话活动时间

    • 会话使用的宽带信息

    • 会话负责人信息

  • 媒体信息

    • 媒体类型:视频or音频

    • 传输协议:RTP/UDP/TCP

    • 媒体格式:H.264/MPEG

    • 传输地址和传输端口

格式

SDP会话描述由一个会话级描述(session_level description)和多个媒体级描述(media_level description)组成。会话级(session_level)的作用域是整个会话。其位置是从’v=’行开始到第一个媒体描述为止。媒体级(media_level)描述是对单个的媒体流进行描述(例如传送单个音频或者视频的vlc sdp文件只有短短的几句话,从m=开始,这其实就是个媒体机描述),其位置是从’m=’行开始到下一个媒体描述为止。

v= (协议版本)
o= (所有者/创建者和会话标识符)
s= (会话名称)
i=* (会话信息)
u=* (URI 描述)
e=* (Email 地址)
p=* (电话号码)
c=* (连接信息 ― 如果包含在所有媒体中,则不需要该字段)
b=* (带宽信息)
一个或更多时间描述(如下所示):
​
z=* (时间区域调整)
k=* (加密密钥)
a=* (0个或多个会话属性线路)
0个或多个媒体描述(如下所示)
时间描述
​
t= (会话活动时间)
r=* (0或多次重复次数)
媒体描述
​
m= (媒体名称和传输地址)
i=* (媒体标题)
c=* (连接信息 — 如果包含在会话层则该字段可选)
b=* (带宽信息)
k=* (加密密钥)
a=* (0个或多个会话属性线路)
​
================
SDP字段说明:
​
v字段:协议版本
o字段:-
a字段:a=rtpmap: /  [/] 中的,利用该属性携带编码器厂商名称。该属性表明该流为某厂商编码器编码且是不符合gb28181规定的媒体流,符合国标的媒体流不需要该属性。
例如:a=rtpmap:96 DAHUA/90000
    a=rtpmap:96 HIKVISION/90000
a字段有下列格式:
a字段可携带倍数参数,用于文件下载时控制下载速度。格式: a=downloadspeed:下载倍数(整型)
a字段可携带文件大小参数,用于文件下载时的进度计算。格式: a=filesize:文件大小 (单位:Byte)
a字段可携带setup、connection作为TCP连接协商参数。 a=setup:TCP连接方式(表示本SDP发送者在建立RTP over TCP连接时是主动还是被动发起TCP连接,“active”为主动,“passive”为被动)
a字段可携带SVC参数,用于视频传输时的分辨率或者帧频控制。a=svcspace:空域编码方式 【取值整型。 0:不使用  1:1级增强  2:2级增强  3:3级增强 】  a = svctime:时域编码方式
​
s字段:表示请求媒体流的操作类型,“Play”标识为点播请求   “Playback”标识回播请求   “Download”表示文件下载  “Talk”表示语音对讲;
u字段:u行应填写视音频文件的URL。该URL的取值有两种:简捷方式和普通方式。简捷方式直接采用产生该历史媒体的媒体源(如某个摄像头)的设备ID以及相关参数,参数用“:”分隔;普通方式采样http://储存设备ID[/文件夹]*/文件名;
m字段:描述媒体的媒体类型、端口、传输层协议、负载类型等内容。媒体类型采样“video”标识视频或者视音频混合内容,采样“audio”标识传输音频内容;传输方式采用“RTP/AVP”标识传输层协议为 RTP over UDP,采用“TCP/RTP/AVP”标识传输层协议为RTP over TCP;
t字段:当回放或者下载时,t行值为开始时间,结束时间,采样“ ”分隔;
y字段:十进制整数字符串,标识SSRC值。其中第一位为历史或者实时媒体流的标识位,0为实时,1为历史;第2位到第6位取20位SIP监控域ID之中的4-8位作为域标识;第7-10位作为域内媒体流标识,是一个与当前域内产生的媒体流SSRC值后4位不充分的四位十进制整数;
f字段:f=v/编码格式/分辨率/帧率/码率类型/码率大小  a/编码格式/码率大小/采样率    其中v表示video   a表示audio
SDP实例

# 请求视频流
INVITE sip:[email protected]:7100 SIP/2.0
Via: SIP/2.0/UDP 192.168.40.55:7100;rport;branch=z9hG4bK2480933505
From: ;tag=2249831759
To: 
Call-ID: 821763613                // Call-ID:使用该字段标识一路视频
CSeq: 20 INVITE
Contact: 
Content-Type: Application/SDP
Max-Forwards: 70
User-Agent: NCG V2.6.0.299938
Subject: 00000000001310018021:0,120105110228023020:0
Content-Length:   239
​
v=0
o=00000000001310018021 0 0 IN IP4 192.168.40.55
s=Play                        //Play标识为点播请求   Playback标识回播请求
c=IN IP4 192.168.40.55            //192.168.40.55:音视频流目的地址
t=0 0                        //t行第一参数为视频开始时间  第二个参数为结束时间    t = 0 0表示实时视音频点播
m=video 5552 RTP/AVP 96 97 98   //video:表示请求音视频流  audio:表示请求音频流  5522:音视频流目的端口  RTP/AVP:视频流使用协议 96 97 98:客户端支持码流格式
a=rtpmap:96 PS/90000
a=rtpmap:97 MPEG4/90000
a=rtpmap:98 H264/90000
a=recvonly
a=streamMode:MAIN
y=0999999999
​
# 返回100 trying
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.40.55:7100;rport=7100;branch=z9hG4bK2480933505
From: ;tag=2249831759
To: 
Call-ID: 821763613
CSeq: 20 INVITE
User-Agent: NCG V2.6.0.299938
Content-Length: 0
​
# 携带sdp返回 200
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.40.55:7100;rport=7100;branch=z9hG4bK2480933505
From: ;tag=2249831759
To: ;tag=2885333649
Call-ID: 821763613
CSeq: 20 INVITE
Contact: 
Content-Type: Application/SDP
User-Agent: NCG V2.6.0.299938
Content-Length:   165
​
v=0
o=00000000001310018021 0 0 IN IP4 192.168.40.55
s=Play                
c=IN IP4 192.168.40.66    //192.168.40.66:音视频流源地址      注:视音频源与目的地址不局限于级联服务器本身
t=0 0
m=video 5268 RTP/AVP 96     // video:表示请求视频流  audio:表示请求音频流  5268:音视频流源端口  RTP/AVP:视频流使用协议 96:服务端所选择的码流格式   音视频所使用端口统一使用偶数端口   port+1为rtcp端口
a=rtpmap:96 PS/90000
a=sendonly
y=0100005268
SDP和SIP的关系

SDP一般作为SIP消息的body部分,SIP消息和SDP没有硬性的附属关系,SIP是用来传输信令的,SDP是用来描述流媒体信息的

RTP协议

RTP是一个网络传输协议,IETF RFC3550详细描述了RTP协议内容。GB28181协议中规定了两种方式传输媒体流,一种是将音视频数据打包成MPEG2-PS流然后再通过RTP协议传输,另外一种是直接使用RTP传输裸的音视频流,在实际应用中主要以第一种方式为主

基于RTP的PS封装首先按照ISO/IEC13818-1:20008将视音频流封装成PES包,然后再将PES包封装成PS包, 再将PS包以负载的方式封装成RTP包。进行PS封装时,应将每个视频帧封装为一个PS包,且每个关键帧的PS包中应包含系统头(System Header)和PSM(Program Stream Map),系统头和PSM放置于PS包头之后、第一个PES包之前。典型的视频关键帧PS包结构如图所示,其中PESV为视频PES包,PESA为音频PES包,视频非关键帧的PS包结构中一般不包含系统头和PSM。

img

ZLMediaKit

img

基于C++开发的高性能开源流媒体服务器,特点如下:

  • 支持多种协议(RTSP/RTMP/HLS/HTTP-FLV/WebSocket-FLV/GB28181/HTTP-TS/WebSocket-TS/HTTP-fMP4/WebSocket-fMP4/MP4/WebRTC)

  • 使用多路复用、多线程、异步网络模式开发,性能优越

  • 低延时(100-500ms)

  • 功能完善:支持集群、按需转协议、按需推拉流、先播后推、断连续推等功能

  • 支持多种平台:Windows、Linux、macOS

  • 全面支持H265/H264/AAC/G711/OPUS

  • 支持sdk二次开发

  • 支持0开发直接使用

部署

ZLMediaKit的部署比较简单,根据官方文档部署即可

基于ZLMediaKit的GB28181视频平台demo_第3张图片

可参考:

【精选】国标视频平台搭建(二)ZMLMediaKit部署_zmlmedia 国际协议-CSDN博客

快速开始 · ZLMediaKit/ZLMediaKit Wiki (github.com)

部署完成即可以进行视频推流,这里使用大华摄像头为例

img

因为还没有部署SIP信令服务器,无法接收/下达信令给摄像头所以这里使用RTMP来做测试

设置以上信息后流媒体服务器打印以下信息说明推流成功!

img

RTMP拉流地址拼接(具体参考链接):

拉流地址四元组:

  • 协议

  • 虚拟主机名vhost

  • 应用名:live

  • 流id:0、test

如果有一个RtmpMediaSource,它的4元组分别为 rtmp(RtmpMediaSource固定为rtmp)、somedomain.com、live、0 那么播放这个流媒体源的url对应为:

rtmp://somedomain.com/live/0
rtmps://somedomain.com/live/0
rtmp://127.0.0.1/live/0?vhost=somedomain.com
rtmps://127.0.0.1/live/0?vhost=somedomain.com

我们这里的vhost是__defaultVhost__所以我们的拉流地址是rtmp://10.14.2.7/live/test?vhost=__defaultVhost__(10.14.2.7是流媒体服务器的地址)

基于ZLMediaKit的GB28181视频平台demo_第4张图片

目测使用rtmp推流的延时在3s左右,现在我们的流媒体服务器已经搭建成功!

开始实施

整体逻辑

实时视音频点播采用SIP协议中的INVITE方法实现会话连接,采用RTP/RTCP协议(IETF RFC3550)实现媒体传输。需要注意的是,实时视音频点播需要上述的媒体流保活机制。客户端主动发起的实时视音频点播流程见下图

基于ZLMediaKit的GB28181视频平台demo_第5张图片

部署信令服务器

部署完流媒体服务器之后还需要一个sip信令服务器来接受国标设备信息和下达指令,这里采用开源的基于C++的Sip Server作为demo部署

项目地址:BXC_SipServer: 基于C++开发的国标GB28181流媒体信令服务器。 采用BXC_SipServer+ZLMediaKit。完整搭建一个可以接收,摄像头通过国标协议推流到国标GB28181流媒体服务器,然后进行RTSP/RTMP/HTTP-FVL/HLS/WS/SRT等协议分发。 (gitee.com)

参考项目中的教程很轻松的就完成了部署,并再main.cpp文件中找到sip服务器所绑定的信息

#include "SipServer.h"
#include "Utils/Log.h"
int main(int argc, char *argv[]) {
    LOGI("");
​
    ServerInfo info(
            "BXC_SipServer",   //name
            "1234567890123456",  //
            "10.14.2.7",        // ip
            15060,              // sip服务器的端口
            10000,              // 流媒体服务器的端口
            "34020000002000000001", //sip服务器编号
            "3402000000",       // 域
            "123456789",
            1800,
            3600);
​
    SipServer sipServer(&info);
    sipServer.loop();
​
    return 0;
根据以上信息来配置大华摄像头的国标服务器信息:

基于ZLMediaKit的GB28181视频平台demo_第6张图片

配置好之后服务器会接收到sip的相关请求,注册成功之后大华平台摄像头的状态会变为绿色

基于ZLMediaKit的GB28181视频平台demo_第7张图片

GB28181推流/拉流

信令服务器部署后会告诉摄像头接收国标28181推流的端口10000,结合前面我们已经部署了ZLMediaKit,所以我们现在已经将大华摄像头的视频内容通过GB28181的形式推送到了我们的流媒体服务器了,流传输采用RTP的形式。(这里注意如果rtmp和国标28181都配置了,好像只有一个生效)

基于ZLMediaKit的GB28181视频平台demo_第8张图片

拉流时只需要将__defaulthost__改为流媒体服务器的ip即可,地址:rtsp://10.14.2.7/rtp/05F5E101

基于ZLMediaKit的GB28181视频平台demo_第9张图片

目测延时在1.7s左右,如果关闭音频推流则在1.5-1.6左右,比rtmp推流的延时更低,但是长时间拉流发现存在延时累积情况,使用vlc拉流3小时后延时增加到4秒左右

参考文章

技术解码 | GB28181/SIP/SDP 协议 - 知乎 (zhihu.com)

【精选】国标视频平台搭建(二)ZMLMediaKit部署_zmlmedia 国际协议-CSDN博客

快速开始 · ZLMediaKit/ZLMediaKit Wiki (github.com)

你可能感兴趣的:(音视频)