如何设计 GB28181 的流媒体接入层:SRS6 与 ZLMediaKit 的接入流程、配置案例与交互说明

流媒体接入层是 GB28181 项目中最容易被低估、却实际最关键的模块。
很多工程团队将精力集中在 SIP 注册、目录查询、录像查询上,却忽略了真正把流接进来、转出去、提供播放能力的——正是流媒体接入层。

本文聚焦四个核心问题:

  • 为什么 GB28181 平台必须设计专门的流媒体接入层
  • SRS6ZLMediaKit 在 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. 协作架构总览

核心职责边界:

  • 设备 → 平台:SIP 信令(注册、查询、控制)
  • 设备 → 流媒体服务器:RTP/PS 媒体流
  • 流媒体服务器 → 业务系统:播放协议输出
  • 平台不直接处理媒体数据,流媒体服务器不直接和设备打 SIP

4. 流媒体接入层应该承担哪些职责

一个真正可用的流媒体接入层,至少要承担以下 8 类职责:

  1. RTP 接收
    • 能按会话打开端口,接收设备推送的 RTP/PS 流
  2. 流标识管理
    • 能把 streamIdssrccallIddeviceIdchannelId 对齐
  3. 协议转换
    • 把国标 RTP/PS 转成 RTMP、HTTP-FLV、HLS、WebRTC 等
  4. 播放输出
    • 给浏览器、APP、播放器提供统一播放地址
  5. 生命周期管理
    • 会话建立、超时清理、BYE 关闭、异常回收
  6. 媒体状态回调
    • 流注册、断流、无人观看、录制完成等事件反馈给平台
  7. 安全与鉴权
    • 播放地址鉴权、回调鉴权、管理 API 安全
  8. 扩展能力
    • 录制、截图、转码、转推、集群、边缘节点等

如果缺少这层,平台就会出现典型问题:

  • 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 核心交互流程

6.3 为什么 ZLM 模式成为主流

ZLM 的设计哲学与 GB28181 的 INVITE 模式天然契合:

匹配点 说明
时机控制 平台决定何时开流,INVITE 时机由平台掌握
端口绑定 平台知道流应落到哪个端口,每路会话独立
职责分离 流媒体服务器只负责媒体,不碰 SIP

两种端口模式的对比:

模式 streamId 适用场景
固定端口(默认 10000 默认使用 ssrc 作为 stream_id 测试、快速验证
动态端口(openRtpServer 平台指定业务化 streamId 大规模生产环境

7. ZLMediaKit 的典型配置案例

下面给一个适合 GB28181 项目使用的 示意配置
注意:不同版本配置项名字可能略有差异,落地时请按你实际版本核对。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
[general]
mediaServerId=zlm-gb28181-01
flowThreshold=1024

[api]
secret=your_zlm_secret
apiDebug=0

[http]
port=8080
sslport=8443
charSet=utf-8

[rtsp]
port=554
sslport=332
authBasic=0

[rtmp]
port=1935
sslport=0

[rtc]
port=8000
tcpPort=8001
externIP=your.public.ip.or.domain

[rtp_proxy]
port=10000
timeoutSec=15
dumpDir=

[hook]
enable=1
timeoutSec=10
on_publish=http://127.0.0.1:28181/hooks/zlm/on_publish
on_stream_none_reader=http://127.0.0.1:28181/hooks/zlm/on_stream_none_reader
on_flow_report=http://127.0.0.1:28181/hooks/zlm/on_flow_report
on_server_started=http://127.0.0.1:28181/hooks/zlm/on_server_started

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——顺序不可颠倒

顺序不能错。

正确顺序:

  1. 向 ZLM 申请 RTP 接收端口
  2. 拿到 port
  3. 构造 SDP
  4. 再发 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 推荐架构

这个方案非常适合:

  • 业务系统播放量大
  • 需要 WebRTC
  • 需要公网播放能力
  • 需要强互联网分发协议支持

9.4 为什么很多团队会这样做

因为 GB28181 的难点和 SRS6 的强项不完全重合:

  • GB28181 的难点是 SIP/MANSCDP/设备兼容
  • SRS6 的强项是播放协议分发、互联网场景、WebRTC

所以把它们解耦,通常更合理。


10. SRS6 接入 GB28181 的两种常见做法

10.1 做法 A:SRS6 直接接入 GB28181

这是 SRS6 官方已经支持的一种模式:

  1. 设备把 SIP 服务器配置为 SRS6
  2. SRS6 接收设备 REGISTER
  3. 设备注册成功后,SRS6 自动发起 INVITE
  4. 设备通过 TCP 单端口把媒体推送到 SRS6
  5. SRS6 输出 HTTP-FLV / HLS / WebRTC 等地址

这个模式的优点是:

  • 部署简单
  • 链路短
  • 上手快

但限制也很明确:

  • 更适合直播预览
  • 不适合要求完整国标控制闭环的大平台
  • 官方公开能力中暂不覆盖回看、语音对讲、加密传输等复杂场景

10.2 做法 B:GB28181 平台接流,转推到 SRS6

流程:

  1. 平台通过 GB28181 与设备建立会话
  2. 平台或接流服务收 RTP/PS
  3. 转封装为 RTMP
  4. 推给 SRS6
  5. SRS6 输出 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
listen              1935;
max_connections 1000;
daemon off;
srs_log_tank console;

http_api {
enabled on;
listen 1985;
}

http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}

stream_caster {
enabled on;
caster gb28181;
listen 9000;

sip {
enabled on;
listen 5060;
candidate your.reachable.ip
}

output rtmp://127.0.0.1/live/[stream];
}

rtc_server {
enabled on;
listen 8000;
candidate your.public.ip.or.domain;
}

这份配置对应的是:

  • 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
listen              1935;
max_connections 1000;
daemon off;
srs_log_tank console;

http_api {
enabled on;
listen 1985;
}

http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}

rtc_server {
enabled on;
listen 8000;
candidate your.public.ip.or.domain;
}

vhost __defaultVhost__ {
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}

hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 6;
hls_window 30;
}

rtc {
enabled on;
rtmp_to_rtc on;
rtc_to_rtmp on;
}
}

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 直控接入流程

14.2 SRS6 分发层流程

14.3 会话关闭流程


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 平台负责控制”让谁发流、发到哪”,流媒体接入层负责承接”流怎么收、怎么转、怎么播”。

SRS6ZLM 的差异可以再压缩成一句话:

ZLM 更像国标接流节点,SRS6 更像互联网分发核心。


18. 落地路线

从零构建 GB28181 平台的推荐推进顺序:

步骤 内容
1 打通 SIP 主流程(注册、目录、录像查询)
2 确定流媒体接入层的职责边界
3 强调国标接入 → 接入 ZLM(openRtpServer + hook)
4 强调互联网播放 → 补 SRS6 分发层
5 统一会话模型、回调模型、streamId 规范