GB28181协议详解

server/2025/2/22 11:22:50/

第一部分:协议基础与设备注册

1.1 协议分层架构

层级协议/规范功能说明
信令控制层SIP (RFC 3261) + GB扩展设备注册、目录订阅、实时点播、云台控制等控制信令
媒体传输层RTP/RTCP (RFC 3550) + PS封装音视频数据封装传输,支持H.264/H.265/G.711/AAC等编码

1.2 设备注册流程(含鉴权算法)

1.2.1 完整信令交互
[设备]                          [SIP服务器]|---- REGISTER (无鉴权) -------->||<---- 401 Unauthorized --------|  WWW-Authenticate: Digest realm="3402000000", nonce="abcd1234"|---- REGISTER (带鉴权头) ------>|  Authorization: Digest username="34020000001320000001", response="xxxx"|<---- 200 OK ------------------|  Expires: 3600
1.2.2 鉴权算法实现
  • 输入参数

    • username:设备ID(如34020000001320000001
    • realm:服务器返回的域(如3402000000
    • password:设备预设密码(如123456
    • nonce:服务器生成的随机数(如abcd1234
    • method:请求方法(REGISTER
    • uri:请求URI(如sip:34020000002000000001@192.168.1.100
  • 计算步骤

    1. 计算 HA1 = MD5(username:realm:password)
    2. 计算 HA2 = MD5(method:uri)
    3. 最终 response = MD5(HA1:nonce:HA2)
  • 代码示例(Python)

  import hashlibdef calculate_response(username, realm, password, nonce, method, uri):ha1 = hashlib.md5(f"{username}:{realm}:{password}".encode()).hexdigest()ha2 = hashlib.md5(f"{method}:{uri}".encode()).hexdigest()return hashlib.md5(f"{ha1}:{nonce}:{ha2}".encode()).hexdigest()

第二部分:实时点播(2025年02月21日场景)

2.1 信令交互全流程

[Client]                                  [Device]|-------- INVITE (SDP Offer) ------------>||<------- 100 Trying ---------------------|  # 临时响应|<------- 200 OK (SDP Answer) ------------|  # 携带设备媒体参数|-------- ACK --------------------------->|  # 确认建立会话|<------- RTP Stream (Port 6000) -------- |  # 媒体流开始传输|-------- BYE --------------------------->|  # 结束会话|<------- 200 OK -------------------------|

2.2 SDP详解(客户端Offer)

v=0
o=34020000002000000001 0 0 IN IP4 192.168.1.100  # 会话发起者标识
s=Play                                              # 会话名称(可自定义)
c=IN IP4 192.168.1.100                             # 客户端接收地址
t=0 0                                              # 时间范围(0表示实时)
m=video 6000 RTP/AVP 96                            # 媒体行:视频,端口6000,负载类型96
a=rtpmap:96 PS/90000                               # PS封装,时钟频率90kHz
a=sendonly                                         # 客户端仅接收(设备发送)
a=control:streamid=1                               # 流标识符(多码流时使用)
a=range:clock=20250221T000000-                     # 时间范围("-"表示持续到结束)
SDP字段逐项解析
字段说明
o=格式:<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
s=会话描述名称(如Play/Live/Playback)
c=连接信息:IN表示Internet,IP4为IPv4地址,192.168.1.100为客户端接收IP
t=时间范围:<start-time> <stop-time>0 0表示永久会话
m=媒体行:<media> <port> <proto> <fmt>video表示视频,6000为端口,RTP/AVP为传输协议
a=rtpmap负载映射:<payload_type> <encoding>/<clock_rate>96对应动态类型,PS为封装格式
a=range时间范围:clock=YYYYMMDDThhmmss-YYYYMMDDThhmmss,实时流可省略结束时间

第三部分:录像回放与下载

3.1 录像查询(MESSAGE信令)

3.1.1 请求消息
<?xml version="1.0"?>
<Query><CmdType>RecordInfo</CmdType>  <!-- 固定指令类型 --><SN>16777216</SN>             <!-- 序列号(递增) --><DeviceID>34020000001320000001</DeviceID><StartTime>20250221T120000</StartTime>  <!-- 起始时间 --><EndTime>20250221T123000</EndTime>      <!-- 结束时间 --><Secrecy>0</Secrecy>          <!-- 保密级别(0-普通,1-机密) --><Type>time</Type>             <!-- 录像类型:time/alarm/manual -->
</Query>
3.1.2 响应消息
<?xml version="1.0"?>
<Response><CmdType>RecordInfo</CmdType><SN>16777216</SN><DeviceID>34020000001320000001</DeviceID><Name>Camera-01</Name><SumNum>1</SumNum>            <!-- 录像片段总数 --><RecordList><Item><DeviceID>34020000001320000001</DeviceID><Name>Channel-1</Name><StartTime>20250221T120000</StartTime><EndTime>20250221T123000</EndTime><FilePath>/videos/20250221_1200.mp4</FilePath>  <!-- 可选字段 --></Item></RecordList>
</Response>

3.2 录像回放(INVITE信令)

3.2.1 SDP关键参数
a=range:clock=20250221T120000-20250221T123000  # 精确时间段
a=control:streamid=2                           # 区分实时流与回放流
3.2.2 回放控制(MESSAGE信令)
<?xml version="1.0"?>
<Control><CmdType>DeviceControl</CmdType><SN>789</SN><DeviceID>34020000001320000001</DeviceID><Scale>4.0</Scale>       <!-- 回放速率(1.0=正常,2.0=2倍速) --><Range>20250221T121500-20250221T122000</Range>  <!-- 拖动到指定位置 -->
</Control>

第四部分:音视频RTP打包规范

4.1 视频封装(H.264/H.265)

4.1.1 PS封装结构
PS Header (0x000001BA) → System Header (0x000001BB) → PES Header (视频流) → H.264/H.265 NALU → PES Header (音频流) → G.711/AAC数据
4.1.2 RTP分片规则
帧类型分片策略
I帧强制分片,每包≤1400字节,FU-A模式(分片头:0x1C + 0x80→首包,0x1C + 0x00→中间包)
P/B帧单包发送(若NALU≤1400字节)或分片发送

H.264分片头示例

RTP Header | FU Indicator (0x1C) | FU Header (0x80) | NALU分片数据  # 首包
RTP Header | FU Indicator (0x1C) | FU Header (0x00) | NALU分片数据  # 中间包
RTP Header | FU Indicator (0x1C) | FU Header (0x40) | NALU分片数据  # 末包(Mark=1)

4.2 音频封装

4.2.1 PS封装音频
  • PES结构
  PES Header (Stream ID=0xC0) | PCM数据(G.711)  # 音频PES包
  • 时间戳同步:音频PTS与视频PTS基于同一90kHz时钟对齐
4.2.2 独立RTP流封装
RTP Header | PCM数据(G.711)  # 直接封装,无分片

SDP声明示例

m=audio 6002 RTP/AVP 8       # G.711U负载类型8
a=rtpmap:8 PCMA/8000/1       # 编码格式与采样率

第五部分:开发注意事项

5.1 时间同步

  • NTP同步:设备与服务器时间误差需<1秒,否则回放请求可能失败
  • RTP时间戳:视频基于90kHz时钟,音频基于采样率(如G.711=8kHz)

5.2 网络适应性

传输模式适用场景优化建议
UDP低延迟、允许少量丢包增加Jitter Buffer(≥500ms)
TCP高可靠性、弱网络环境启用RTP over RTSP(需SDP中声明a=rtcp-mux

5.3 错误处理

  • 注册失败:检查Digest算法实现及设备ID格式(20位数字)
  • 媒体流中断:监控RTCP RR包的丢包率,动态调整码率
  • 时间戳溢出:每26小时重置RTP时间戳(90kHz时钟溢出周期)

附录:关键协议头字段速查

SIP头字段

字段示例值说明
Call-ID123456789@192.168.1.100会话唯一标识(需全局唯一)
CSeq1 INVITE命令序列号(递增)
Contact<sip:34020000001320000001@192.168.1.200>设备实际通信地址

SDP属性字段

属性示例值说明
rtpmap96 PS/90000定义负载类型与编码格式
fmtp96 profile-level-id=42E0H.264编码参数(可选)
controlstreamid=1流标识符(多码流切换)

第六部分:信令表

GB28181 信令全表

信令类型SIP方法关键字段/消息体典型场景响应码
设备注册REGISTERExpires(有效期)、Authorization(鉴权头)、Contact(设备地址)设备上线200 OK / 401 Unauthorized
心跳保活MESSAGE<CmdType>Keepalive</CmdType><Status>OK</Status>维持在线状态200 OK
实时点播请求INVITESDP中的m=videoa=rtpmap:96 PS/90000a=range(时间范围)发起实时视频流200 OK + SDP
录像回放请求INVITESDP中的a=range:clock=起始时间-结束时间a=control:streamid=N请求历史录像流200 OK + SDP
目录查询MESSAGE<CmdType>Catalog</CmdType><DeviceID><SumNum>(通道数)获取设备通道列表200 OK + 通道列表
报警通知NOTIFY<CmdType>Alarm</CmdType><AlarmType>(报警类型)、<AlarmTime>移动侦测/遮挡事件上报200 OK
云台控制MESSAGE<CmdType>DeviceControl</CmdType><PTZCmd>(十六进制指令)摄像头转动/变焦200 OK
录像查询MESSAGE<CmdType>RecordInfo</CmdType><StartTime><EndTime><RecordList>检索设备存储的录像片段200 OK + 录像列表
回放控制MESSAGE<CmdType>DeviceControl</CmdType><Scale>(倍速)、<Range>(跳转时间)快进/快退/拖动进度条200 OK
语音对讲INVITESDP中的m=audioa=rtpmap:8 PCMA/8000(音频编码)双向语音通信200 OK + SDP
设备信息查询MESSAGE<CmdType>DeviceInfo</CmdType><DeviceID>获取设备型号/版本信息200 OK + 设备信息
订阅事件通知SUBSCRIBEEvent: catalog(目录订阅)、Expires(订阅有效期)实时接收设备状态变化200 OK + NOTIFY消息
停止媒体流BYECall-ID(对应会话ID)、CSeq(递增序列号)结束实时预览或回放200 OK
文件下载请求MESSAGE<CmdType>Download</CmdType><FilePath>(文件路径)、<StartTime>下载指定录像文件200 OK + 文件流
网络配置修改MESSAGE<CmdType>ConfigDownload</CmdType><IPAddress><GateWay>远程修改设备网络参数200 OK

关键说明

  1. SDP字段扩展

    • a=control:streamid=N:用于区分多码流(主码流=1,子码流=2)。
    • a=range:clock=YYYYMMDDThhmmss-YYYYMMDDThhmmss:时间格式必须精确到秒。
    • a=rtpmap:96 PS/90000:强制要求视频流使用PS封装,时钟频率90kHz。
  2. XML消息体规范

    • 公共字段<SN>(序列号)、<DeviceID>(20位设备ID)必须唯一且递增。
    • 错误码<StatusCode>(如200成功,400参数错误,404无录像文件)。
  3. 特殊场景处理

    • 分页查询:当录像片段过多时,通过<SumNum>和分页参数分批获取。
    • 鉴权失败:服务器返回401 Unauthorized时,设备需重发带正确Authorization头的请求。

信令交互示例图

[设备注册]
Device -> Server: REGISTER
Server -> Device: 401 Unauthorized
Device -> Server: REGISTER (带鉴权)
Server -> Device: 200 OK[实时点播]
Client -> Device: INVITE (SDP Offer)
Device -> Client: 200 OK (SDP Answer)
Client -> Device: ACK
Device -> Client: RTP流传输[录像回放控制]
Client -> Device: MESSAGE (Scale=2.0)
Device -> Client: 200 OK + 媒体流加速

附:常用CmdType值

CmdType用途关联信令
Keepalive心跳保活MESSAGE
Catalog目录查询MESSAGE
DeviceControl云台/回放控制MESSAGE
RecordInfo录像查询MESSAGE
Alarm报警通知NOTIFY
DeviceInfo设备信息查询MESSAGE
Download文件下载MESSAGE


http://www.ppmy.cn/server/169827.html

相关文章

JavaScript系列(79)--Web Worker 高级应用

Web Worker 高级应用 &#x1f504; Web Worker 为JavaScript提供了真正的多线程能力&#xff0c;让我们能够在后台线程中执行复杂的计算而不阻塞主线程。今天让我们深入探讨Web Worker的高级应用。 Web Worker 概述 &#x1f31f; &#x1f4a1; 小知识&#xff1a;Web Work…

JSON格式,C语言自己实现,以及直接调用库函数(一)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。以下为你提供不同场景下常见的 JSON 格式示例。 1. 简单对象 JSON 对象是由键值对组成&#xff0c;用花括号 {} 包裹&…

Playwright之---网络管理API

Playwright 提供了强大的 网络管理 API&#xff0c;用于控制和管理浏览器的网络活动。这些 API 允许你模拟网络请求和响应、拦截和修改网络请求、模拟网络条件、以及更多网络层级的操作。它们通常用于自动化测试、抓取数据或模拟不同的网络环境。 Playwright 的 网络管理 API 提…

NASM - win64调用ExitProcess不用提供阴影区的原因

文章目录 NASM - win64调用ExitProcess不用提供阴影区的原因概述笔记结论END NASM - win64调用ExitProcess不用提供阴影区的原因 概述 通常来说&#xff0c;win64位程序调用API时&#xff0c;必须提供阴影区(shadow space), 这是win64 API调用的约定。 但是发现一个特例 Exit…

itemgetter() 是 Python operator 模块中的一个函数,主要用于从 字典、列表、元组等数据结构中取值

如何使用 itemgetter()&#xff1f; itemgetter() 是 Python operator 模块中的一个函数&#xff0c;主要用于从 字典、列表、元组等数据结构中取值。它的作用类似一个自动化的 “取值器”&#xff0c;可以让你更方便地提取数据。 1. itemgetter() 取字典 key 的值 如果你有一…

如何在 Vue 应用中实现权限管理?

在 Vue 应用中实现权限管理是确保用户只能访问其有权访问的资源的重要步骤。以下是一些常见的步骤和最佳实践&#xff0c;用于在 Vue 应用中实现权限管理。 1. 定义权限结构 首先&#xff0c;需要定义应用的权限结构。这通常包括角色和权限的概念。 角色和权限示例 角色&am…

哈希表(C语言版)

文章目录 哈希表原理实现(无自动扩容功能)代码运行结果 分析应用 哈希表 如何统计一段文本中&#xff0c;小写字母出现的次数? 显然&#xff0c;我们可以用数组 int table[26] 来存储每个小写字母出现的次数&#xff0c;而且这样处理&#xff0c;效率奇高。假如我们想知道字…

DeepSeek写俄罗斯方块手机小游戏

DeepSeek写俄罗斯方块手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端俄罗斯方块H5文件&#xff1a; 核心功能要求 原生JavaScript实现&#xff0c;适配手机屏幕 …