资讯动态

ZLMediaKit Docker部署实战:WebRTC低延迟配置与视频流媒体搭建

发布时间:2026/9/16 23:15:20 来源:尧图企业网站定制
我在一线用 ZLMediaKit 做直播和音视频互通的经验挺多的这项目在国产开源流媒体方案里确实能打。它把 RTSP、RTMP、HLS、HTTP-FLV、WebRTC 这些协议全揉在一起一个服务就能解决大部分拉流和推流场景而且性能相当稳很多商用网关设备里跑的就是它。之前带团队搭线上环境时我用 Docker 封装了一套标准部署流程今天直接把这套自家用的流程拆给你重点讲讲 WebRTC 的配置细节因为这个是多数人最容易卡住的地方。这次实操我尽量按“先通后优”的思路来先把整条链路跑起来让你能抓到流、看到画面再去抠 WebRTC 的端口、证书、信令这些细节。整个过程我已经在一台干净的 Linux 服务器上完整跑过一遍下面写的每条命令都是我实测敲过的不是从文档里复制粘贴的。1. 项目整体设计与思路拆解1.1 为什么选用 ZLMediaKit 而不是其他流媒体方案聊流媒体服务器很多人第一反应是 SRS 或 Nginx-RTMP。老实说这几个方案我都用过各有各的用武之地。但在“需要多协议互通”和“需要 WebRTC 低延迟”这两个点上ZLMediaKit 确实有它的独到之处。先说多协议接入的问题。一个典型的业务场景可能是这样的摄像头通过 RTSP 推流浏览器端想用 WebRTC 看实时画面手机端要求 HLS 能播放老板电脑上又只装了 VLC 想直接拉 RTSP 流。传统做法是部署多套服务RTSP 一套、HLS 一套、WebRTC 再搞一套然后中间还要做协议转换运维复杂度直接飙升。ZLMediaKit 的做法是一个进程全部搞定底层统一收流上层按需输出不同协议天然就是一套完整的接入方案。再说 WebRTC。市面上大部分开源流媒体服务对 WebRTC 的支持要么是实验性质要么根本不支持。但 ZLMediaKit 的 WebRTC 支持做得比较成熟因为它内部实现了 RTP 推拉流和 DTLS 协商配合内置的 HTTPS 信令接口可以很快搭出一条低延迟通路。我实测下来在局域网条件下 WebRTC 的端到端延迟可以控制在 300 到 500 毫秒左右这个水平已经能胜任很多互动场景了。1.2 Docker 部署的核心优势与我的选型考量用 Docker 部署 ZLMediaKit我觉得最核心的价值不是“省事”两个字能概括的而是它把部署这件事变成了一种确定性极高的操作。裸机部署 ZLMediaKit 需要处理一堆环境依赖。它依赖 FFmpeg、OpenSSL、libsrtp 等库不同发行版还涉及不同的问题经常遇到编译失败的情况。虽然有官方编译好的发布包但版本升级和依赖管理仍然是个麻烦。C 工程的编译比较磨人十几分钟到半小时都有可能编译中途报库缺失也是常有的事。Docker 把这些麻烦挡在镜像外面。我这次用官方镜像一条 docker run 就能把服务拉起来所有库依赖、二进制文件和默认配置都封装好了。更重要的是Docker 镜像的移植性非常好——我在测试服务器上验证过的配置打包成 compose 文件后可以整体迁移到生产服务器环境完全一致没有“在我这好好的怎么到你那就挂了”这种问题。还有一个细节是版本回滚。Docker 镜像的 tag 机制让版本管理变得很直接——出问题就切回上一个 tag 重新部署整个过程按分钟计这在裸机环境下很难做到这么干脆。1.3 ZLMediaKit 的整体架构与核心功能拆解为了让后面的部署和排错更有方向感我先把 ZLMediaKit 的内部结构简单梳理一下。ZLMediaKit 采用的是“单一收流、按需输出”的架构。推流端或拉流端通过不同协议接入后媒体数据最终会被统一转为内部的 MediaSource 格式。然后所有输出协议RTMP、HLS、HTTP-FLV、WebRTC 等共享这份数据源按需拉取。这种设计的最大好处是一个流只需要从源端收取一份可以无限分发到各个协议端避免重复拉流导致源站压力过大。核心功能上它内置了几个关键模块流媒体服务模块负责 RTSP、RTMP、HLS、HTTP-FLV、WebRTC 等协议的监听、接收和分发。RTP 收流与推流模块底层用 RTP 协议承载音视频数据对接 GB28181 等场景时这个模块就是核心。后台管理与 API 模块通过 HTTP 接口实现流列表查询、推流鉴权、录像管理等操作对接业务系统非常方便。WebRTC 信令模块负责 SDP 协商和 DTLS 握手让浏览器可以直接推拉流。后面所有操作包括 Docker 端口映射和 WebRTC 配置都和这几个模块有关。先对这个架构有个基本认知配置参数时就不会懵。2. 环境准备与 Docker 快速部署实操2.1 环境要求与镜像选择先聊环境。ZLMediaKit 本身对硬件要求不高但如果涉及视频转码就会有额外消耗。我这次只做流媒体转发不涉及转码使用的是一台 4 核 8G 的云主机带宽 10M 独享跑起来非常轻松。如果你是 2 核 4G 的机器只做协议转发也完全够用。操作系统要求很简单只要能装 Docker 就行Linux、Windows、macOS 都可以。但如果是生产环境我强烈建议用 Linux 服务器。Windows 跑 Docker Desktop 因为虚拟化层多了一层网络性能和稳定性都不如 Linux 原生 Docker尤其是做 WebRTC 这种 UDP 密集型业务时Windows 宿主机可能出现端口映射和防火墙的额外问题。镜像选择方面其实 ZLMediaKit 官方在 Docker Hub 上有发布但网络原因有时候拉取不太顺畅。不过说实话国内很多云环境拉 Docker Hub 都还靠谱多试几次通常能成功。我这次直接用的是官方镜像tag 选的是 master 分支的最新构建。如果拉取遇到困难可以配置一下镜像加速源。但要注意网上那些第三方加速源经常失效建议优先尝试官方拉取实在不行再考虑其他途径。2.2 使用 docker run 快速启动 ZLMediaKit镜像拉下来之后一条命令就能启动服务。这是我实际使用的启动命令docker run -d --name zlmediakit \ -p 1935:1935 \ -p 554:554 \ -p 10000:10000 \ -p 10000:10000/udp \ -p 8080:8080 \ -p 8443:8443 \ -p 8000:8000 \ zlmediakit/zlmediakit:master这条命令里的端口映射非常关键每一个端口都对应 ZLMediaKit 的一种能力我来逐个拆解1935RTMP 协议默认端口。RTMP 推流和拉流都走这里是做直播时最常用的端口。554RTSP 协议默认端口。安防摄像头和海康、大华等设备基本都走 RTSP这个端口必须放开。10000/tcpWebRTC 的 HTTP 信令端口。浏览器和服务器做 SDP 协商时要走这个端口。10000/udpWebRTC 的 RTP 媒体传输端口。音视频数据实际传输走的这里UDP 协议低延迟的关键。8080HTTP 管理后台和 API 端口。查看流列表、获取播放地址都要用。8443HTTPS 端口。WebRTC 在非 localhost 环境下强制要求 HTTPS这个端口就用来提供 HTTPS 服务。8000HTTP-FLV 和 HTTP-TS 端口。网页端用 flv.js 播放时走这个端口。启动完成后检查一下容器状态docker ps | grep zlmediakit看到状态是 Up 就说明容器活着。但容器活着不代表服务真的能用了还需要做一步验证。2.3 验证服务端口是否正常监听我习惯用 telnet 或 nc 快速验证端口是否真的在监听。在宿主机上执行telnet 127.0.0.1 8080能进入命令交互界面就说明管理后台端口通了。同理可以验证 1935、554 等端口。从容器内部检查也是一个好思路docker exec -it zlmediakit netstat -lntp这条命令能查看到容器内正在监听的 TCP 端口。如果有服务协议没有正常启动这里能看出一些端倪。比如如果你发现自己映射了 1935 但实际容器里没有监听 1935那说明 RTMP 模块可能没启动成功需要进一步查日志。端口通了之后就可以试试通过 API 接口验证服务状态curl http://127.0.0.1:8080/index/api/getServerConfig这个接口会返回 ZLMediaKit 的完整服务配置信息如果返回了 JSON 数据说明 API 服务是在正常工作的。但会提示需要鉴权参数这个我们后面会讲到怎么处理。2.4 使用 docker compose 管理配置与启动参数docker run 适合快速启动但如果配置比较复杂或者需要版本化归档我推荐用 docker compose。它的好处是可以把端口映射、环境变量、配置挂载写在一个 YAML 文件里后续维护和应用迁移都很清晰。我常用的 docker-compose.yml 配置长这样version: 3.8 services: zlmediakit: image: zlmediakit/zlmediakit:master container_name: zlmediakit restart: always network_mode: host volumes: - ./config.ini:/opt/media/conf/config.ini - ./www:/opt/media/www environment: - TZAsia/Shanghai这里我用的是 network_mode: host而不是端口映射。这个选择很关键后面讲 WebRTC 的时候会解释为什么。如果不需要改动太多配置直接用端口映射模式就够用了。但如果你需要调整 ZLMediaKit 的内部参数比如修改 RTP 超时时间、调整录像路径把配置文件挂载出来会更方便。3. ZLMediaKit 后台管理与基础拉流测试3.1 后台管理系统介绍与 Secret 配置ZLMediaKit 自带一个后台管理系统通过浏览器访问 http://服务器IP:8080 就能打开。这个后台页面可以看到服务器状态、流列表、协议统计等信息界面虽简单但功能齐全。不过有一个地方很多人第一次用会卡住页面操作和 API 调用都需要校验 secret 配置。ZLMediaKit 默认的 secret 是035c73f7-bb6b-4889-a715-d9eb2d1925cc如果用的是默认配置通过 API 时需要带上这个 secret 参数。页面登录是另一套机制默认用户名 admin密码 admin。首次登录后建议尽快修改默认密码这个后台不仅能看状态还能直接踢流、关闭服务器权限很高。如果使用 docker compose 并挂载自定义 config.ini可以在配置文件中修改 api 相关参数包括 secret 和后台登录密码。修改完重启容器即可生效docker-compose restart3.2 通过 rstp 模拟推流验证服务是否可用服务启动后最直接的验证方式就是自己推一路流进去然后用不同协议拉出来看看能不能通。我常用 FFmpeg 做模拟推流。先用 ffmpeg 生成一个测试视频源然后推到 ZLMediaKit 的 RTMP 端口ffmpeg -re -f lavfi -i testsrcsize1280x720:rate25 -f lavfi -i sinefrequency1000:sample_rate44100 \ -c:v libx264 -preset veryfast -tune zerolatency -c:a aac \ -f flv rtmp://127.0.0.1:1935/live/test这条命令会生成一个带声音的彩色测试画面推流到 rtmp://127.0.0.1:1935/live/test其中/live/是应用名test是流 ID。推流成功后用 FFmpeg 再拉RTSP流测试ffplay rtsp://127.0.0.1:554/live/test如果画面能流畅播放说明 RTSP 链路是通的。同时也可以试试 HTTP-FLV 拉流ffplay http://127.0.0.1:8000/live/test.flv如果也能播放说明 HTTP-FLV 输出也正常。到这里基础的服务验证就算通过了。3.3 常见拉流地址格式汇总与使用场景ZLMediaKit 的拉流地址格式是根据不同协议区分的总结一下我经常用到的格式你可以按实际场景选择RTMP 地址适合 VLC 播放器、OBS 拉流、传统直播场景rtmp://IP:1935/live/testRTSP 地址适合安防设备对接、VLC 播放器rtsp://IP:554/live/testHTTP-FLV 地址适合浏览器端 flv.js 播放http://IP:8000/live/test.flvHLS 地址适合移动端 Safari、微信内置浏览器播放http://IP:8080/live/test/hls.m3u8WebRTC 地址适合浏览器端低延迟播放后面会重点讲webrtc://IP:10000/live/test这里特别说明一下HLS 是切片拉流延迟在 3 到 10 秒上下适合对实时性要求不高的场景。WebRTC 延迟在毫秒级适合连麦、监控、在线教育这些对实时性要求很高的场景。拉流验证通过后整个服务基础链路就跑通了。下面进入本文的核心重点——WebRTC 配置。4. WebRTC 全过程配置详解重点4.1 WebRTC 在 ZLMediaKit 中的工作原理简述WebRTC 和其他流媒体协议最大的区别是它不采用传统的“服务端分发”模式而是通过 P2P 或近端媒体网关的机制用 UDP 协议实现低延迟的音视频传输。ZTMediaKit 作为 WebRTC 的媒体网关实现了一套完整的信令交互和媒体转发逻辑。浏览器发起 WebRTC 请求时首先通过 HTTPS 与 ZLMediaKit 建立信令连接完成 SDPSession Description Protocol协商。这个 SDP 里面包含了双方的媒体能力、编解码器参数、IP 地址和端口信息。协商完成后浏览器和 ZLMediaKit 之间会建立 DTLS 加密通道然后通过 SRTP 协议传输音视频数据。这个过程中不需要转码数据是直接从源端封装成 RTP 包发出去的所以延迟才能控制在很低水平。理解了这条链路下面配置时你就能知道每一步到底在干什么配置端口是为了让 UDP 媒体传输有地方进来配置证书是为了让信令走 HTTPS配置公网 IP 是为了让 SDP 中包含正确的地址信息。4.2 关键前置端口映射与 host 网络模式选择WebRTC 配置最常遇到的坑就是端口映射不完整导致媒体传输失败。如果你用 docker run 的端口映射方式启动需要确保同时映射了 TCP 10000 端口信令和 UDP 10000 端口媒体传输-p 10000:10000/tcp -p 10000:10000/udp很多云服务器默认只开了 TCP 的安全组UDP 端口没放通结果 WebRTC 的信令协商成功但媒体数据根本传不过来画面一直卡在“连接中”。排查这类问题先检查安全组和防火墙的 UDP 端口。不过即便如此我个人的经验是如果条件允许WebRTC 相关服务直接用 host 网络模式最省心。使用 host 模式容器直接共享宿主机网络栈不需要做端口映射也不涉及 NAT 转换WebRTC 的 UDP 端口可以直接使用 ZLMediaKit 配置的原始端口。下面是 host 模式启动的 compose 配置version: 3.8 services: zlmediakit: image: zlmediakit/zlmediakit:master container_name: zlmediakit restart: always network_mode: host volumes: - ./config.ini:/opt/media/conf/config.ini - ./www:/opt/media/www有人担心 host 模式会不会有安全风险其实主要看你如何管理防火墙规则。我自己的方案是服务器用防火墙只放开需要的端口1935、554、8080、8443、8000、10000/udp 等配合 ZLMediaKit 的 api 鉴权安全性是有保障的。4.3 配置文件中的 WebRTC 核心参数说明如果使用默认配置ZLMediaKit 已经预置了 WebRTC 参数通常可以正常工作。但如果需要定制就需要挂载并修改 config.ini 文件。在 config.ini 中关键的 WebRTC 配置参数集中在[rtc]段落[rtc] # 对外暴露的 IP 地址如果部署在公网务必改成公网 IP server_ip0.0.0.0 # 媒体传输端口范围 port_range10000:10000 # 启动外部 RTMP 转 RTC 的开关 rtmp_to_rtc1 # 启动 RTC 转 RTMP 的开关 rtc_to_rtmp1 # WebRTC 的 TCP 端口同时也用于 HTTPS 信令 tcp_port10000 # 保持时间超过该时间没有数据则认为连接断开 keepalive_sec30其中server_ip是最容易出问题的参数。如果部署在云服务器上需要把这个 IP 改成服务器的公网 IP 地址否则 SDP 协商时告诉浏览器的还是容器内部的 IP浏览器访问不到。如果是单机局域网部署保持默认值 0.0.0.0 一般也能正常工作因为 ZLMediaKit 会尝试从网卡上自动探测本机 IP。port_range10000:10000表示媒体传输用 10000 这个 UDP 端口。如果你需要支持更多并发 WebRTC 连接可以把范围调大比如 10000:10200表示 10000 到 10200 这 200 个 UDP 端口都可以用于媒体传输。端口范围越大并发能力越强。4.4 WebRTC 所必需的 HTTPS 证书配置流程WebRTC 有个硬性要求浏览器只有在 HTTPS 或 localhost 环境下才允许使用 getUserMedia 和 RTCPeerConnection 能力。所以如果用公网 IP 访问服务就必须给 ZLMediaKit 配置 HTTPS 证书。ZLMediaKit 默认已经生成了一个自签名证书用于 8443 端口的 HTTPS 服务。但这个证书是自签的浏览器会报“不安全”警告而且很多浏览器在证书无效的情况下会直接拦截 WebRTC 会话。我推荐用 Lets Encrypt 签一个免费证书配置到 ZLMediaKit 里。步骤大概是用 certbot 申请证书certbot certonly --standalone -d yourdomain.com申请成功后证书文件在/etc/letsencrypt/live/yourdomain.com/目录下。把证书拷贝到宿主机上然后在 docker compose 中挂载到容器内volumes: - ./ssl:/opt/media/ssl修改 config.ini 中的证书配置[general] # 配置 HTTPS 证书文件 ssl_cert/opt/media/ssl/fullchain.pem ssl_key/opt/media/ssl/privkey.pem如果没有域名可以在测试环境使用自签名证书然后把浏览器设置成忽略证书错误。但生产环境这么做会有隐患浏览器兼容性也不稳定能用正式证书还是尽量用正式证书。4.5 浏览器端 WebRTC 播放测试全流程配置完成后怎么验证 WebRTC 真的工作正常呢最简单的方式是用 ZLMediaKit 自带的 WebRTC 播放器页面。浏览器访问http://服务器IP:8443/webrtc/如果证书配置正确会打开一个测试页面。输入流的地址live/test点播放如果能看到画面说明整套 WebRTC 链路已经通了。但要注意如果你用的是 HTTP8080端口访问后台WebRTC 依然可能无法正常工作因为浏览器要求安全上下文。所以务必用 HTTPS8443访问 WebRTC 测试页面。还有一个更直接的验证方式是用官方提供的 webrtc 播放器页面源码放在 Nginx 或 ZLMediaKit 的 www 目录下用 HTTP 方式访问试试。但在 Chrome 下基本都会失败这是浏览器的安全策略决定的。我实测时最常用的方式是直接用 ZLMediaKit 后台管理页面自带的播放按钮选择 WebRTC 类型播放。这个播放器封装了完整的 SDP 协商过程不用自己写一行前端代码。如果播放器能出画面那说明信令通了、DTLS 握手成功了、UDP 媒体传输也通了整条 WebRTC 链路是健康的。如果画面一直转圈出不来优先检查几个地方UDP 10000 端口是否放通、server_ip 是否配置正确、证书是否有效、浏览器控制台有没有报错信息。下面我把常见问题单独列一个章节来说。5. 常见问题与排查技巧实录5.1 端口冲突导致容器启动失败现象docker run 执行后容器状态显示 Exited日志里提示端口已被占用。原因宿主机上已经有一个服务占用了 1935 或其他映射端口最常见的是本机装了其他流媒体服务。排查netstat -lntp | grep 1935找到占用端口的进程后要么停掉旧服务要么修改 ZLMediaKit 的端口映射docker run -d --name zlmediakit \ -p 19350:1935 \ -p 55400:554 \ ...修改映射后对外访问地址也要相应变化比如 RTMP 地址变成rtmp://IP:19350/live/test。5.2 WebRTC 连接超时信令通但媒体不通现象能打开 WebRTC 测试页面也能建立连接但播放器一直显示连接中控制台报 ICE 连接失败。原因这是 WebRTC 配置中最常见的问题信令走通了但媒体端口不通。原因几乎都是 UDP 端口没有放通或者 server_ip 配置不正确。排查步骤确认安全组/防火墙放通了 10000/udp 端口。用 tcpdump 抓包确认 UDP 流量是否到达服务器tcpdump -i any udp port 10000检查 config.ini 中的 server_ip 是否设置为公网 IP。如果用的是 NAT 映射的网络需要配置 external_ip 参数。我排查 WebRTC 连接问题时90% 的根因都出在这几个地方按这个顺序排查基本能定位。5.3 后台页面打不开或 API 鉴权失败现象浏览器访问http://IP:8080长时间加载不出页面或者 API curl 返回 “Unauthorized” 错误。原因后台打不开大概率是服务没起来或者端口没映射对API 鉴权失败是 secret 参数没带对。解决先确认容器状态docker logs -f zlmediakit看日志里有没有启动失败的错误信息。API 调用时带上正确的 secretcurl http://127.0.0.1:8080/index/api/getServerConfig?secret035c73f7-bb6b-4889-a715-d9eb2d1925cc返回 JSON 数据即说明 API 正常工作。5.4 推流成功但拉流无画面现象FFmpeg 推流成功日志显示已经开始播放但拉流端黑屏或卡在原地。原因可能是编解码器问题也可能是服务器没有开启对应的输出协议。排查用 RTSP 拉流测试确认服务端收流正常ffplay rtsp://127.0.0.1:554/live/test检查推流端的编码参数。ZLMediaKit 对 H.264 和 H.265 的视频编码支持得比较好但音频编码上如果你推 AAC 没问题如果推的是 MP3 格式有些播放器可能不支持建议统一用 AAC。查看 ZLMediaKit 的日志里面会明确记录推流协议、编码参数、拉流协议等信息。5.5 高并发下的性能优化建议如果做的是正式项目后续可能有大量用户同时拉流这里有几个我实际调优过的小建议加大 UDP 端口范围。WebRTC 每路流都要占用一个独立端口默认 10000:10000 只有 1 个可用端口并发一高直接不够用。建议改大port_range10000:10200调整线程池参数。ZLMediaKit 默认会根据 CPU 核心数自动配置线程池但如果你知道服务器的实际情况可以在 config.ini 里显式配置[general] thread_pool_size8日志级别调低。生产环境建议把日志级别从 debug 改成 info 或 warn减少不必要的日志 IO 消耗[general] log_levelwarn负载均衡。单台 ZLMediaKit 撑不住的场景可以多台部署用 Nginx 做 443 和 10000/udp 的负载均衡后端挂多个 ZLMediaKit 实例。但要注意WebRTC 的负载均衡比 HTTP 复杂UDP 层的负载均衡需要 Nginx 编译支持 stream 模块或者用更专业的负载均衡方案。5.6 关于音频编码和浏览器兼容性的两个提醒如果推的是 H.265 视频流要注意 Chrome 和 Firefox 大部分版本不支持 WebRTC 传输 H.265所以 WebRTC 拉流端看到的可能只有黑屏或只有声音。这也是为什么我前面特意提到生产环境如果考虑 WebRTC 播放尽量用 H.264 编码。音频方面部分老的摄像头音频格式比如 G.711A在 WebRTC 里也可能存在兼容问题。建议让 ZLMediaKit 不做音频转码由推流端统一推 AAC 音频这样 WebRTC 播放端兼容性最好。如果推流端没有这个能力可以考虑在 ZLMediaKit 前面加一个 FFmpeg 转码节点把音频统一转成 AAC。6. ZLMediaKit 实际业务接入与扩展思路6.1 用 ZLMediaKit API 对接业务系统的常见方式跑通了基础的流媒体服务之后实际业务中往往需要和现有系统打通。ZLMediaKit 提供了比较完整的 HTTP API 接口可以很方便地做流管理、鉴权和状态查询。我最常用的是这几个接口获取所有在线流curl http://127.0.0.1:8080/index/api/getMediaList?secret035c73f7-bb6b-4889-a715-d9eb2d1925cc返回所有 MediaSource 信息包括流协议、拉流客户端数量、编码格式等。做流状态监控就拿这个接口轮询。主动关闭流curl http://127.0.0.1:8080/index/api/close_streams?secret035c73f7-bb6b-4889-a715-d9eb2d1925ccvhost__defaultVhost__applivestreamtestforce1当检测到非法推流或需要主动断流时通过这个接口可以强制关闭。添加流代理拉流代理curl -X POST http://127.0.0.1:8080/index/api/addStreamProxy?secret035c73f7-bb6b-4889-a715-d9eb2d1925ccvhost__defaultVhost__applivestreamproxy_streamurlrtsp://192.168.1.100:554/stream1这个接口解决的是“把第三方 RTSP 流拉进来转成其他协议”的问题。很多安防场景就是通过 addStreamProxy 把海康、大华的 RTSP 流拉进来再统一输出成 HLS 或 WebRTC 给上层业务使用。这套 API 对接方式可以把 ZLMediaKit 当成一个流媒体中间件嵌到自己的业务系统里推流、拉流、状态管理都在自己的后台控制。6.2 GB28181 国标设备接入场景补充如果你做的是安防监控平台可能还会遇到 GB28181 国标设备的接入场景。ZLMediaKit 对 GB28181 有内置支持设备可以通过 SIP 协议注册到 ZLMediaKit然后按国标流程发起 INVITE 请求把媒体流推上来。这个场景下ZLM 扮演的是 SIP 服务器加媒体服务器的双重角色。设备侧需要配置 SIP 服务器地址、端口、SIP 用户 ID 等参数ZLM 侧需要开启 GB28181 相关的配置段并在后台配置 SIP 服务器的监听端口和密码。如果这方面有实际需求建议单独展开一个专题来讲。这里先提一句有国标设备接入需求时用 ZLMediaKit 可以省去单独部署一套国标网关的成本。6.3 从单机扩展到集群的架构思路很多项目一开始单机就够用但上线后用户量上来了单机性能开始吃紧。这时候再做架构升级需要提前有心理预期服务器从单机到集群改动最大的是负载均衡层ZLM 本身还是相对独立的。最简单有效的横向扩展方案在前面加一层负载均衡根据流 ID 的哈希或者 IP 哈希把请求分发到不同 ZLMediaKit 节点。每个节点只管自己负责的流节点间不做状态同步这样架构最简单。但要注意WebRTC 的分发和 RTMP/HLS 不一样它在信令层面和媒体层面都涉及动态端口负载均衡必须同时处理 UDP 流量。普通的四层负载均衡只能基于 IP 和端口转发做不到基于流内容的路由。如果对 WebRTC 做集群建议优先考虑“一个域名对应一个节点组节点组内按需调度”的方式。做集群之前先算清楚单机 ZLMediaKit 能撑多少路并发这和分辨率、码率、协议类型都有关系不能一概而论。我自己的经验是在普通云服务器上做 WebRTC 转发单机能扛住几百路并发如果做 HLS 分发几千路都不成问题因为 HLS 走 CDN 分发后源站压力不大。6.4 与 CDN 配合使用的一个参考路径还有一种常见的生产架构是 ZLMediaKit 作为源站CDN 负责边缘分发。推流端推到 ZLMediaKitZLM 转成 HLS 或 HTTP-FLV 后在源站提供拉流CDN 从源站回源把流分发给终端用户。这个架构的好处是ZLMediaKit 不需要关心终端用户的网络质量只负责和 CDN 之间稳定回源。CDN 节点可以覆盖全国甚至全球的终端用户延迟和卡顿都大幅减少。需要注意的一点是CDN 回源协议要选对。HLS 回源是 HTTP 拉流最稳定HTTP-FLV 回源延迟更低但需要 CDN 支持。WebRTC 目前 CDN 支持还不普遍如果你需要 WebRTC 的极低延迟又不想自己部署边缘节点可以先选一家支持 WebRTC 分发的 CDN 厂商或者自己做一些边缘协议转换的方案。7. 写在最后关于踩坑和选型的一些个人体会我前后在两个正式项目里深度用过 ZLMediaKit一个是安防监控平台一个是互动直播。部署方式从一开始的裸机编译到后来统一切到 Docker体验上确实提升了一大截。裸机编译 ZLMediaKit 最痛苦的经历是一次系统更新后某个依赖库版本不对了重新编译折腾了好几个小时才把环境修好。后来换成 Docker再也没碰过类似的问题。WebRTC 这个部分是我见过最容易让新手放弃的地方。很多人一开始用 WebRTC 连不通就开始怀疑是不是服务器有问题其实极大概率就是 UDP 端口没开或证书没过。我的建议是先把基础链路跑通再用 WebRTC 做进阶别一步到位全都想配好。先用 RTMP 推流拉流验证服务正常再切 WebRTC 排查问题这样定位问题会快很多。最后留一个小建议做生产环境部署时一定要把配置文件的版本管理做起来。用 Git 管住 config.ini 和 docker-compose.yml每次变更记录清楚原因。流媒体服务最怕“跑得好好的突然不对了”这时候往前翻一下配置变更历史往往能很快定位问题。ZLMediaKit 的前景我还是比较看好的它在多协议互通和 WebRTC 支持上已经积累了不少优势社区也很活跃。如果你选型时正在纠结流媒体服务器用哪家从这套 Docker 部署方案入手花一晚上跑通体验一遍你的判断会清晰很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价