• 基于ZLMediaKit的GB28181视频平台demo


    GB28181

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

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

    协议架构:

    img

    注册

    注册过程:

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

    参数解读:

    1. REGISTER sip:34020000002000000001@3402000000 SIP/2.0
    2. Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1371463273
    3. From: sip:34020000001320000003@3402000000;tag=2043466181
    4. To: sip:34020000001320000003@3402000000
    5. Call-ID: 1011047669
    6. CSeq: 1 REGISTER
    7. Contact: sip:34020000001320000003@192.168.137.11:5060
    8. Max-Forwards: 70
    9. User-Agent: IP Camera
    10. Expires: 3600
    11. Content-Length: 0
    12. =================
    13. 第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协议版本。
    14. 第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。  
    15. 第3行为From头,From头中包含了请求发送方的逻辑标识,在GB28181协议中是发送请求的设备国标ID和域国标ID信息。tag参数是为了身份认证的,值为随机数字字符。  
    16. 第4行为To头,To头在SIP协议中是为了标明请求接收方的逻辑标识的,在GB28181协议中填写的是发送请求的设备国标ID和域国标ID信息。  
    17. 第5行为Call-ID头,Call-ID头是全局唯一的,在同一个session中保持一致,在不同session中不同。  
    18. 第6行为CSeq头,CSeq头又叫Command Seqence(命令队列),用于标识命令顺序,值为序号+Method,序号部分为无符号整数,最大值为2^31。序号起始值是随机的,后续在同一个session中依次递增,比如发1 REGISTER没返回--->再发2 REGISTER--->没返回--->再发3 REGISTER--->这时返回了2 REGISTER就知道是第2个请求得到了响应。对于ACK和CANCLE中的CSeq与INVITE中的Cseq保持一致。  
    19. 第7行为Contact头,Contact头包含源的URI信息,用来给响应消息直接和源建立连接用。在GB28181协议中为SIP设备编码@源IP地址端口。  
    20. 第8行为Max-Forwards头,Max-Forwards头用于设置包最大中转次数,默认是70。  
    21. 第9行为User-Agent头,User-Agent头用于设置关于UA的信息,用户可以自定义。  
    22. 第10行为Expires头,Expires头表示超时时间。  
    23. 第11行为Content-Length头,Content-Length头表示SDP消息的长度,因为REGISTER消息不需要SDP,因此为0。        
                                            
    保活

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

    img

    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:bob@zte.com SIP/2.0 /r/n

    • 消息体

    • body

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

    • INVITE:发起会话请求

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

    • CANCEL:取消请求

    • BYE:终止会话

    • OPTIONS:查询服务器能力

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

    状态码
    状态码msg含义
    100Trying试呼叫
    180Ringing振铃
    181Call is Being Forwarded呼叫正在前转
    200OK成功响应
    302Moved Temporarily临时迁移
    400Bad Request错误请求
    401Unauthorized未授权
    403Forbidden禁止
    404Not Found用户不存在
    408Request Timeout请求超时
    480Temporarily Unavailable暂时无人接听
    486Busy Here线路忙
    504Server Time-out服务器超时
    600Busy 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=’行开始到下一个媒体描述为止。

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

    1. # 请求视频流
    2. INVITE sip:00000000001310018021@192.168.40.66:7100 SIP/2.0
    3. Via: SIP/2.0/UDP 192.168.40.55:7100;rport;branch=z9hG4bK2480933505
    4. From: ;tag=2249831759
    5. To:
    6. Call-ID: 821763613               // Call-ID:使用该字段标识一路视频
    7. CSeq: 20 INVITE
    8. Contact:
    9. Content-Type: Application/SDP
    10. Max-Forwards: 70
    11. User-Agent: NCG V2.6.0.299938
    12. Subject: 00000000001310018021:0,120105110228023020:0
    13. Content-Length:   239
    14. v=0
    15. o=00000000001310018021 0 0 IN IP4 192.168.40.55
    16. s=Play                       //Play标识为点播请求   Playback标识回播请求
    17. c=IN IP4 192.168.40.55           //192.168.40.55:音视频流目的地址
    18. t=0 0                       //t行第一参数为视频开始时间 第二个参数为结束时间   t = 0 0表示实时视音频点播
    19. m=video 5552 RTP/AVP 96 97 98   //video:表示请求音视频流 audio:表示请求音频流  5522:音视频流目的端口 RTP/AVP:视频流使用协议 96 97 98:客户端支持码流格式
    20. a=rtpmap:96 PS/90000
    21. a=rtpmap:97 MPEG4/90000
    22. a=rtpmap:98 H264/90000
    23. a=recvonly
    24. a=streamMode:MAIN
    25. y=0999999999
    26. # 返回100 trying
    27. SIP/2.0 100 Trying
    28. Via: SIP/2.0/UDP 192.168.40.55:7100;rport=7100;branch=z9hG4bK2480933505
    29. From: ;tag=2249831759
    30. To:
    31. Call-ID: 821763613
    32. CSeq: 20 INVITE
    33. User-Agent: NCG V2.6.0.299938
    34. Content-Length: 0
    35. # 携带sdp返回 200
    36. SIP/2.0 200 OK
    37. Via: SIP/2.0/UDP 192.168.40.55:7100;rport=7100;branch=z9hG4bK2480933505
    38. From: ;tag=2249831759
    39. To: ;tag=2885333649
    40. Call-ID: 821763613
    41. CSeq: 20 INVITE
    42. Contact:
    43. Content-Type: Application/SDP
    44. User-Agent: NCG V2.6.0.299938
    45. Content-Length:   165
    46. v=0
    47. o=00000000001310018021 0 0 IN IP4 192.168.40.55
    48. s=Play                
    49. c=IN IP4 192.168.40.66   //192.168.40.66:音视频流源地址     注:视音频源与目的地址不局限于级联服务器本身
    50. t=0 0
    51. m=video 5268 RTP/AVP 96     // video:表示请求视频流 audio:表示请求音频流  5268:音视频流源端口 RTP/AVP:视频流使用协议 96:服务端所选择的码流格式   音视频所使用端口统一使用偶数端口   port+1为rtcp端口
    52. a=rtpmap:96 PS/90000
    53. a=sendonly
    54. 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的部署比较简单,根据官方文档部署即可

    img

    可参考:

    【精选】国标视频平台搭建(二)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是流媒体服务器的地址)

    img

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

    开始实施

    整体逻辑

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

    img

    部署信令服务器

    部署完流媒体服务器之后还需要一个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服务器所绑定的信息

    1. #include "SipServer.h"
    2. #include "Utils/Log.h"
    3. int main(int argc, char *argv[]) {
    4.    LOGI("");
    5.    ServerInfo info(
    6.            "BXC_SipServer",   //name
    7.            "1234567890123456",  //
    8.            "10.14.2.7",        // ip
    9.            15060,              // sip服务器的端口
    10.            10000,              // 流媒体服务器的端口
    11.            "34020000002000000001", //sip服务器编号
    12.            "3402000000",       // 域
    13.            "123456789",
    14.            1800,
    15.            3600);
    16.    SipServer sipServer(&info);
    17.    sipServer.loop();
    18.    return 0;
    根据以上信息来配置大华摄像头的国标服务器信息:

    img

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

    img

    GB28181推流/拉流

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

    img

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

    img

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

    参考文章

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

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

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

  • 相关阅读:
    【服务器数据恢复】Linux网站服务器的数据恢复案例
    使用.NET简单实现一个Redis的高性能克隆版(四、五)
    基于PHP+MySQL的校园二手旧书回收捐赠系统
    3D开发工具HOOPS:助力Navisworks数据处理与3D模型可视化!
    Spark面试题
    【TcaplusDB知识库】TcaplusDB新增机型介绍
    HTML页面
    Linux C语言进阶
    【2023】windows下安装libevent
    Struts2的拦截器
  • 原文地址:https://blog.csdn.net/alianfibakic/article/details/134562673