从零理解GB28181-3(流媒体接入)
如何设计 GB28181 的流媒体接入层:SRS6 与 ZLMediaKit 的接入流程、配置案例与交互说明
流媒体接入层是 GB28181 项目中最容易被低估、却实际最关键的模块。
很多工程团队将精力集中在 SIP 注册、目录查询、录像查询上,却忽略了真正把流接进来、转出去、提供播放能力的——正是流媒体接入层。本文聚焦四个核心问题:
- 为什么 GB28181 平台必须设计专门的流媒体接入层
SRS6与ZLMediaKit在 GB28181 架构中的定位差异- 平台、设备、流媒体服务器之间的交互流程
- 可落地的配置案例与平台设计要点
1. 为什么需要流媒体接入层
GB28181 不是”只做信令”的协议。仅完成 SIP 部分,平台能覆盖的能力有限:
| SIP 能力覆盖 | 用户实际需求 |
|---|---|
| 设备注册、保活 | 实时看视频 |
| 目录查询、录像查询 | 回放录像 |
| 设备控制 | Web / APP / 播放器同时分发 |
| — | HTTP-FLV / RTSP / HLS / WebRTC 输出 |
两者之间存在一个关键缺口:SIP 只管”让设备推流”,不管”流怎么收、怎么转、怎么播”。
这就是流媒体接入层存在的理由——它负责:
| 职责 | 说明 |
|---|---|
| RTP 接收 | 按会话打开端口,接收设备 RTP/PS 推流 |
| 流标识管理 | 将 streamId / ssrc / callId / deviceId / channelId 对齐 |
| 协议转换 | 国标 RTP/PS → RTMP / HTTP-FLV / HLS / WebRTC |
| 播放输出 | 为浏览器、APP、播放器提供统一播放地址 |
| 生命周期管理 | 会话建立、超时清理、BYE 关闭、异常回收 |
| 媒体状态回调 | 流注册、断流、无人观看等事件反馈给平台 |
| 安全与鉴权 | 播放鉴权、回调鉴权、API 访问控制 |
| 扩展能力 | 录制、截图、转码、转推、集群、边缘节点 |
缺少此层的典型症状:SIP 成功但用户看不到流;流来了不知道归属谁;会话结束资源未释放;多路流无法隔离。
2. 结论先行:ZLM 与 SRS6 的定位差异
两者虽同称”流媒体服务器”,在 GB28181 项目中的定位却不同:
2.1 ZLMediaKit——GB28181 友好型接流节点
ZLM 在 GB28181 项目中的典型角色:
| 能力 | 说明 |
|---|---|
| RTP 接收端口管理 | 支持固定端口和动态端口(openRtpServer) |
| 流接入与承载 | 接收设备 RTP/PS,自适应 PS / TS |
| 多协议输出 | RTSP / RTMP / HTTP-FLV / HLS / WebRTC |
| 平台可控 | 通过 HTTP API 精确控制每个端口和会话 |
最适合的模式: 平台负责 SIP 和业务编排 → ZLM 专门负责开端口、收流、出流。分工清晰,和国标 INVITE 模式天然契合。
2.2 SRS6——互联网分发核心 + 可选轻量接入
SRS6 的核心强项:
| 强项 | 适用场景 |
|---|---|
| RTMP / HTTP-FLV / HLS | Web 页面直播、移动端播放 |
| WebRTC | 低延迟实时通信 |
| 多协议分发 | 大规模并发观看 |
SRS6 也提供了 GB28181 直接接入能力,但有明确的能力边界:
| 支持 | 不支持 |
|---|---|
| GB/T 28181-2016 | UDP SIP / UDP 媒体 |
| TCP SIP 信令 | 回看、语音对讲 |
| TCP 单端口媒体传输 | 加密传输、下级平台 |
| AAC 音频编码 | 完整 PTZ HTTP API |
SRS6 在 GB28181 项目中的两种定位:
| 定位 | 适用场景 |
|---|---|
| 轻量一体化接入 | 摄像头直接注册到 SRS6,自动邀请推流,快速出地址 |
| 分发层/播放出口 | 平台或网关接流后转推给 SRS6,SRS6 负责协议转换和多协议输出 |
选型结论:
| 需求 | 推荐 |
|---|---|
| 国标接入 + 精细会话控制 + RTP 端口按需开关 | ZLMediaKit |
| Web/App 播放 + WebRTC + 互联网分发 | SRS6 |
| 两者都要 | 平台 + ZLM 接流 + SRS6 分发(最常见的大型项目形态) |
3. 协作架构总览
flowchart LR
A[前端设备] -->|REGISTER / MESSAGE / INVITE / BYE| B[GB28181 平台]
B -->|HTTP API / 控制| C[流媒体接入层]
B -->|MySQL / Redis| D[(平台存储)]
A -->|RTP/PS 流| C
C -->|HTTP-FLV / RTMP / RTSP / HLS / WebRTC| E[业务系统 / Web / APP / 播放器]
核心职责边界:
- 设备 → 平台:SIP 信令(注册、查询、控制)
- 设备 → 流媒体服务器:RTP/PS 媒体流
- 流媒体服务器 → 业务系统:播放协议输出
- 平台不直接处理媒体数据,流媒体服务器不直接和设备打 SIP
4. 流媒体接入层应该承担哪些职责
一个真正可用的流媒体接入层,至少要承担以下 8 类职责:
- RTP 接收
- 能按会话打开端口,接收设备推送的 RTP/PS 流
- 流标识管理
- 能把
streamId、ssrc、callId、deviceId、channelId对齐
- 能把
- 协议转换
- 把国标 RTP/PS 转成 RTMP、HTTP-FLV、HLS、WebRTC 等
- 播放输出
- 给浏览器、APP、播放器提供统一播放地址
- 生命周期管理
- 会话建立、超时清理、BYE 关闭、异常回收
- 媒体状态回调
- 流注册、断流、无人观看、录制完成等事件反馈给平台
- 安全与鉴权
- 播放地址鉴权、回调鉴权、管理 API 安全
- 扩展能力
- 录制、截图、转码、转推、集群、边缘节点等
如果缺少这层,平台就会出现典型问题:
- SIP 成功了但用户看不到流
- 流来了但不知道属于谁
- 会话结束了资源没有释放
- 同一设备多路流之间无法正确隔离
5. 两种主流设计路线
路线 A:平台直控流媒体节点(推荐)
最常见的 GB28181 平台 + ZLMediaKit 方案。流程:
1 | 业务请求 → 平台申请 RTP 端口 → 构造 INVITE+SDP → 设备推流 → 流媒体转码 → 返回播放地址 |
| 优势 |
|---|
| 控制链路清晰,每步可追踪 |
| 会话与流资源精准绑定 |
| 平台可按业务精确控制每路流的开关 |
路线 B:SRS6 接入 / 分发层
两种形态:
形态一——直接接入: 设备 → SRS6(SIP) → SRS6(自动INVITE) → 输出地址
形态二——分发层: 设备 → 平台(GB28181) → 接流网关(RTP/PS) → RTMP → SRS6(分发)
| 优势 | 局限 |
|---|---|
| 链路短、上手快 | 功能边界窄(TCP/2016/AAC 约束) |
| 分发能力强、协议丰富 | 多一层接入网关 |
| WebRTC/大并发友好 | 流ID/会话/回调设计需更规范 |
6. ZLMediaKit 接入标准流程
核心模式:平台负责 SIP,ZLM 负责开口接流和分发。
6.1 角色分工
| 组件 | 职责 |
|---|---|
| GB28181 平台 | 设备注册、目录/录像查询、INVITE+SDP 生成、callId/ssrc/streamId 管理、流开关控制 |
| ZLMediaKit | 打开 RTP 接收端口、接收 RTP/PS(自适应 PS/TS)、支持 H.264/H.265/AAC/G711/Opus、输出多协议播放地址、提供 HTTP API 和 webhook |
6.2 核心交互流程
sequenceDiagram
participant Biz as 业务系统
participant P as GB28181 平台
participant Z as ZLMediaKit
participant D as 前端设备
Biz->>P: 请求实时点播(deviceId, channelId)
P->>Z: openRtpServer(streamId, tcpMode)
Z-->>P: 返回接收端口(mediaPort)
P->>D: INVITE + SDP(mediaIp, mediaPort, ssrc)
D-->>P: 100 Trying / 200 OK
D->>Z: RTP/PS 推流
Z-->>P: 流注册 / publish hook
P-->>Biz: 返回播放地址(http-flv/rtsp/webrtc)
6.3 为什么 ZLM 模式成为主流
ZLM 的设计哲学与 GB28181 的 INVITE 模式天然契合:
| 匹配点 | 说明 |
|---|---|
| 时机控制 | 平台决定何时开流,INVITE 时机由平台掌握 |
| 端口绑定 | 平台知道流应落到哪个端口,每路会话独立 |
| 职责分离 | 流媒体服务器只负责媒体,不碰 SIP |
两种端口模式的对比:
| 模式 | streamId | 适用场景 |
|---|---|---|
固定端口(默认 10000) |
默认使用 ssrc 作为 stream_id |
测试、快速验证 |
动态端口(openRtpServer) |
平台指定业务化 streamId | 大规模生产环境 |
7. ZLMediaKit 的典型配置案例
下面给一个适合 GB28181 项目使用的 示意配置。
注意:不同版本配置项名字可能略有差异,落地时请按你实际版本核对。
1 | [general] |
7.1 这些配置分别解决什么问题
[api].secret- 平台通过 HTTP API 控制 ZLM 时的鉴权密钥
[http].port- 平台调用 ZLM API 的入口
[rtsp]/[rtmp]/[rtc]- 对外分发协议端口
[rtp_proxy]- 为 RTP 接收与代理能力提供端口能力;默认固定端口模式和动态端口模式都依赖这一层
[hook]- 让平台知道什么时候有流注册、什么时候无人观看、什么时候应回收
7.2 平台侧与 ZLM 对接时最关键的 4 个参数
media.url- 平台访问 ZLM 的 API 地址
media.ip- 写入 SDP 里让设备推流到的接收地址
media.id- 流媒体节点唯一标识,便于多节点管理
media.secret- 调 ZLM API 时使用的密钥
8. 平台设计要点(ZLM 模式)
8.1 先开端口,再发 INVITE——顺序不可颠倒
顺序不能错。
正确顺序:
- 向 ZLM 申请 RTP 接收端口
- 拿到
port - 构造 SDP
- 再发 INVITE
如果你先发 INVITE,再去申请端口,就容易出现:
- 设备已经开始推流
- 流媒体端口还没准备好
- 首包丢失
- 会话建立失败
这里补一条非常重要的工程经验:
- 如果你走的是 ZLM 默认固定端口接收模式,可以不必为每一路会话提前动态开端口
- 如果你走的是 平台主控 + 精细会话管理模式,仍然更推荐先调用
openRtpServer
原因是:
- 固定端口模式适合测试、简化接入、快速验证
- 动态端口模式更适合大规模平台,便于将
deviceId/channelId/callId/streamId和收流端口精确绑定
8.2 streamId 必须稳定可推导
推荐拼接规则:
| 场景 | streamId 格式 |
|---|---|
| 实时流 | {deviceId}_{channelId} |
| 回放流 | {deviceId}_{channelId}_{startTime}_{endTime} |
不做统一规范的后果:日志查询困难、回调关联混乱、播放地址不可预期。
8.3 会话必须缓存
最低缓存字段: callId / streamId / ssrc / mediaIp / mediaPort / inviteType / expiresAt
缺少缓存时,流断开、BYE 到达或无人观看后均无法正确回收资源。
9. SRS6 的两种用法
SRS6 在 GB28181 场景下不应被简单理解为”只能做分发层”。更准确的说法:
| 模式 | 说明 |
|---|---|
| 精简型接入服务 | 设备直接注册到 SRS6,自动 INVITE 推流,输出播放地址 |
| 分发层 | 平台/网关负责 GB28181 会话,接流后转推给 SRS6 做协议转换和分发 |
9.1 直接接入模式
设备直接把 SIP 服务器配置为 SRS6。5 个约束:
| # | 约束 |
|---|---|
| 1 | 编译时启用 --gb28181=on(推荐 5.x/6.x) |
| 2 | 设备侧选择 GB/T28181-2016 |
| 3 | 传输协议选 TCP |
| 4 | 音频编码配为 AAC |
| 5 | 公网部署时需配置 candidate |
9.2 分发层模式
平台或网关负责 GB28181 会话 → 收 RTP/PS → 转封装为 RTMP → 注入 SRS6 → 多协议输出。
为什么很多团队选择此方案? GB28181 的难点在 SIP/MANSCDP/设备兼容,而 SRS6 的强项在播放分发、互联网场景和 WebRTC——两者解耦后各司其职。
9.3 推荐架构
flowchart LR
A[前端设备] -->|REGISTER / INVITE / RTP| B[GB28181 平台或接入网关]
B -->|RTMP 推流 / 标准流注入| C[SRS6]
C -->|HTTP-FLV / HLS / WebRTC / RTMP| D[浏览器 / App / 播放器]
B -->|MySQL / Redis| E[(平台存储)]
这个方案非常适合:
- 业务系统播放量大
- 需要 WebRTC
- 需要公网播放能力
- 需要强互联网分发协议支持
9.4 为什么很多团队会这样做
因为 GB28181 的难点和 SRS6 的强项不完全重合:
- GB28181 的难点是 SIP/MANSCDP/设备兼容
- SRS6 的强项是播放协议分发、互联网场景、WebRTC
所以把它们解耦,通常更合理。
10. SRS6 接入 GB28181 的两种常见做法
10.1 做法 A:SRS6 直接接入 GB28181
这是 SRS6 官方已经支持的一种模式:
- 设备把 SIP 服务器配置为 SRS6
- SRS6 接收设备 REGISTER
- 设备注册成功后,SRS6 自动发起 INVITE
- 设备通过 TCP 单端口把媒体推送到 SRS6
- SRS6 输出 HTTP-FLV / HLS / WebRTC 等地址
sequenceDiagram
participant D as 前端设备
participant S as SRS6
participant Biz as 业务系统/播放器
D->>S: REGISTER(TCP, GB/T28181-2016)
S-->>D: 200 OK
S->>D: INVITE + SDP(candidate, media port)
D->>S: TCP 单端口媒体推流
S-->>Biz: 输出 FLV / HLS / WebRTC 播放地址
这个模式的优点是:
- 部署简单
- 链路短
- 上手快
但限制也很明确:
- 更适合直播预览
- 不适合要求完整国标控制闭环的大平台
- 官方公开能力中暂不覆盖回看、语音对讲、加密传输等复杂场景
10.2 做法 B:GB28181 平台接流,转推到 SRS6
流程:
- 平台通过 GB28181 与设备建立会话
- 平台或接流服务收 RTP/PS
- 转封装为 RTMP
- 推给 SRS6
- SRS6 输出 HTTP-FLV / HLS / WebRTC
这是最稳的一种做法。
sequenceDiagram
participant Biz as 业务系统
participant P as GB28181 平台
participant G as 接流服务/网关
participant S as SRS6
participant D as 前端设备
Biz->>P: 请求播放
P->>D: INVITE + SDP
D->>G: RTP/PS 推流
G->>S: 转推 RTMP
S-->>Biz: HTTP-FLV / HLS / WebRTC 地址
10.3 做法 C:使用支持 GB28181 caster 的接入方案输出到 SRS6
一些社区方案会采用:
stream_caster- GB28181 接入插件
- SIP 网关
- 定制接入服务
让接入层把 GB28181 媒体最终输出成:
rtmp://127.0.0.1/live/[stream]
然后由 SRS6 继续分发。
这类方案的本质仍然是:
- SRS6 主要负责分发
- GB28181 接入逻辑由专门的接入层完成
11. SRS6 的典型配置案例
11.1 直接接入 GB28181 的示意配置
下面是一份更贴近官方用法的 SRS6 GB28181 示意配置:
1 | listen 1935; |
这份配置对应的是:
5060:接收 GB28181 SIP 注册9000:接收媒体 TCP 单端口流output rtmp://127.0.0.1/live/[stream]- 将 GB28181 流注入 SRS 内部 RTMP 通道
http_server / rtc_server- 输出 FLV / HLS / WebRTC
11.2 作为分发层的配置
下面给一个更偏”分发层”的 SRS6 示意配置。
1 | listen 1935; |
11.3 这份配置的意义
listen 1935- 接收 RTMP 推流
http_api- 便于平台获取状态、做运维管理
http_server- 对外提供 HTTP-FLV/HLS 访问
rtc_server- 提供 WebRTC 能力
http_remux- RTMP 自动转 HTTP-FLV
hls- 自动切 HLS
rtc- 支持 RTMP 与 WebRTC 互转
11.4 适合怎样的业务
这类配置非常适合:
- Web 页面直播观看
- 大量移动端播放
- 需要低延迟 WebRTC
- 国标流进来后转成统一互联网协议
12. SRS6 与 ZLM 的交互差异
这一节非常重要,因为它决定你的平台怎么设计。
| 维度 | ZLMediaKit | SRS6 |
|---|---|---|
| 在 GB28181 项目中的典型定位 | RTP 接入节点 + 分发节点 | 分发核心 / 互联网播放出口 |
| 与 GB28181 平台关系 | 常由平台直接 HTTP API 控制 | 可直接接入,也可由平台或接入网关转推进入 |
| 最适合的接法 | 平台直控开 RTP 端口,再发 INVITE | 轻量直连接入,或平台/网关先接流再推给 SRS |
| WebRTC 能力 | 有 | 很强,互联网播放场景成熟 |
| GB28181 媒体接入友好度 | 很高 | 已支持直接接入,但能力边界比平台直控方案更窄 |
| 会话管理方式 | 与国标会话天然绑定紧密 | 直接接入时偏轻量,分发层模式更偏播放分发视角 |
一句话总结:
- ZLM 更像”平台直控的国标接流节点”
- SRS6 更像”可直接接入的轻量国标服务 + 播放分发节点”
13. 平台与流媒体服务器之间到底要交换什么信息
不管你用的是 ZLM 还是 SRS6,平台和流媒体接入层之间至少要交换以下信息:
| 字段 | 说明 |
|---|---|
| mediaServerId | 流媒体节点标识 |
| streamId | 平台侧流 ID |
| deviceId | 设备 ID |
| channelId | 通道 ID |
| callId | SIP 会话 ID |
| ssrc | 流标识 |
| mediaIp | 接收流 IP |
| mediaPort | 接收流端口 |
| inviteType | PLAY / PLAYBACK / DOWNLOAD |
| status | INIT / ACTIVE / CLOSED |
| playUrls | 对外播放地址集合 |
这张表的本质是在说明:
流媒体服务器不是”黑盒播放器”,它必须和平台共享会话上下文。
14. 三个最关键的流程图
14.1 ZLM 直控接入流程
flowchart TD
A[业务请求播放] --> B[平台申请 RTP 端口]
B --> C[ZLM 返回 mediaPort]
C --> D[平台发 INVITE + SDP]
D --> E[设备向 ZLM 推 RTP/PS]
E --> F[ZLM 生成播放地址]
F --> G[平台返回给业务系统]
14.2 SRS6 分发层流程
flowchart TD
A[业务请求播放] --> B[平台建立 GB28181 会话]
B --> C[接流服务收到 RTP/PS]
C --> D[接流服务转推 RTMP 到 SRS6]
D --> E[SRS6 生成 HTTP-FLV/HLS/WebRTC]
E --> F[业务系统播放]
14.3 会话关闭流程
sequenceDiagram
participant Biz as 业务系统
participant P as 平台
participant M as 流媒体服务器
participant D as 设备
Biz->>P: 停止播放
P->>D: BYE
D-->>P: 200 OK
P->>M: 关闭端口/释放流会话
M-->>P: 回收成功
P-->>Biz: 返回停止成功
15. 配置设计时最容易漏掉的点
15.1 对外播放地址和接流地址不要混淆
很多人第一次做会犯一个错误:
- 把写进 SDP 的
mediaIp - 和返回给前端的播放地址域名
混在一起。
实际上这两个地址经常完全不是一回事:
mediaIp- 设备用来推流的接收地址
playUrl- 浏览器或 APP 用来播放的出口地址
15.2 多网卡和 NAT 场景必须提前设计
特别是:
- 流媒体服务器有内网 IP 和公网 IP
- 平台部署在容器里
- WebRTC 走公网
这时必须明确:
- 设备应该推到哪个 IP
- 浏览器应该访问哪个 IP
- 回调里返回哪个地址
否则”设备能推流、用户却看不到”的问题会非常常见。
15.3 流 ID 必须统一规范
建议统一约定:
- 实时流:
{deviceId}_{channelId} - 回放流:
{deviceId}_{channelId}_{start}_{end}
这样:
- 日志更容易查
- 回调更容易关联
- 回放和实时不会互相冲突
15.4 要有无人观看回收策略
尤其是接入层和分发层都存在时,更要考虑:
- 没人看了要不要自动关闭
- 是先关闭播放器出口,还是先发 BYE
- 录像回放是否允许后台继续跑
这些都是平台产品策略,不只是媒体技术问题。
16. 什么时候选 ZLM,什么时候选 SRS6
如果你的目标是:
- 强调 GB28181 国标接入
- 强调平台对会话精确控制
- 强调 RTP 端口按需开关
- 强调和 SIP 会话紧耦合
优先选:
- ZLMediaKit
如果你的目标是:
- 强调 Web / APP 播放
- 强调 WebRTC
- 强调大规模互联网播放协议分发
- 强调 RTMP/HTTP-FLV/HLS 的统一输出
优先选:
- SRS6
如果你的目标是”两边都要”,最常见的组合是:
- 平台 + ZLM 接流 + SRS6 分发
这也是很多复杂项目最终会走到的形态。
17. 一句话理解这篇文章
如果要把流媒体接入层压缩成一句话,可以记住:
GB28181 平台负责控制”让谁发流、发到哪”,流媒体接入层负责承接”流怎么收、怎么转、怎么播”。
而 SRS6 和 ZLM 的差异可以再压缩成一句话:
ZLM 更像国标接流节点,SRS6 更像互联网分发核心。
18. 落地路线
从零构建 GB28181 平台的推荐推进顺序:
| 步骤 | 内容 |
|---|---|
| 1 | 打通 SIP 主流程(注册、目录、录像查询) |
| 2 | 确定流媒体接入层的职责边界 |
| 3 | 强调国标接入 → 接入 ZLM(openRtpServer + hook) |
| 4 | 强调互联网播放 → 补 SRS6 分发层 |
| 5 | 统一会话模型、回调模型、streamId 规范 |