news 2026/9/10 10:30:39

如何把 ZLMediaKit 接入你的 Spring Boot 系统:从搭建流媒体服务器到跑通直播的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何把 ZLMediaKit 接入你的 Spring Boot 系统:从搭建流媒体服务器到跑通直播的完整指南

如何把 ZLMediaKit 接入你的 Spring Boot 系统:从搭建流媒体服务器到跑通直播的完整指南

【免费下载链接】ZLMediaKitWebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framework based on C++11项目地址: https://gitcode.com/GitHub_Trending/zl/ZLMediaKit

本文以 C++ 编写的流媒体服务器 ZLMediaKit 为例,演示如何用 Spring Boot 对接它,实现 RTMP 推流、HLS 播放、WebHook 回调和流媒体 API 调用。适合想在业务系统里加入流媒体能力的 Java 开发者和新手读者。

它替开发者省掉了什么

自己写流媒体服务器,意味着要亲自实现 RTSP、RTMP、HLS 等一堆协议,每种协议都有自己的连接协商、分包、重传机制,还要处理时间戳对齐和权限校验。这套脏活累活,正是 C++ 写的流媒体引擎该干的事。ZLMediaKit 负责协议适配、帧处理和一转多协议分发:一路 RTMP 推进来,就能转成 RTSP、HTTP-FLV、HLS、WebRTC 等多种形式播出去。

Java 这边剩下的就是业务逻辑。通常有三类问题是留给 Spring Boot 层处理的:

  • 鉴权:这个用户能不能推流、能不能播放,由业务系统说了算,媒体服务器只负责"问一句"
  • 状态同步:流创建、销毁时,数据库和前端要实时知道
  • 生命周期管理:按需拉流、无人观看自动关闭、断流恢复

所以两者的分工很清晰:ZLMediaKit 管"流怎么进出",Spring Boot 管"谁能看、什么时候看、看完记什么"。它们之间的所有通信都走 HTTP,且只有两种形式——你调它的接口,它回调你。

一条从克隆仓库到跑通第一条流的完整路径

克隆并编译流媒体服务器

克隆仓库后在 Linux 环境(需要 cmake 和 C++11 工具链)下编译,产物是MediaServer可执行文件:

git clone https://gitcode.com/GitHub_Trending/zl/ZLMediaKit cd ZLMediaKit mkdir build && cd build cmake .. && make -j4

编译完成后文件位于release/linux/Debug/。注意进程默认加载的是同目录下config.ini(cmake 会从 conf/config.ini 拷贝过去),直接改conf/里的文件不会生效。配置里先认准两项:

  • api.secret:敏感接口的访问密钥,通过 127.0.0.1 本地访问时可不带
  • hook.*:所有 WebHook 回调地址,默认全部关闭

推一条流、播一条流

启动进程后,用一次最轻的 API 调用确认服务活着:

curl "http://127.0.0.1/index/api/getServerConfig"

返回一份包含全部配置的 JSON,说明服务正常。接着用 FFmpeg 在本地推一条流(RTMP 是推流领域的事实标准协议,绝大多数推流软件都用它):

ffmpeg -re -stream_loop -1 -i test.mp4 -c copy -f flv rtmp://127.0.0.1/live/streamA

推流地址由app/stream两段组成,这里live是应用名、streamA是流名。推上去之后,浏览器播放器打开http://127.0.0.1/live/streamA.flv就能播 HTTP-FLV;或者用任意支持 m3u8 的播放器播 HLS(基于切片文件的渐进式播放协议)地址http://127.0.0.1/index.hls/live/streamA.m3u8

把 Spring Boot 接到媒体服务器 API 上

引擎侧就绪后,Java 侧只需要一个能访问http://127.0.0.1:80/index/api的 HTTP 客户端。建议把地址和密钥收进application.properties统一管理:

media.api.base=http://127.0.0.1:80/index/api media.secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc

到这里整体形态就出来了:MediaServer 是常驻进程,负责流处理;Spring Boot 是业务入口,负责鉴权与状态记录,前者完全由后者通过 HTTP 驱动。

请求-响应 与 事件驱动:两种交互模式拆解

同步调用:Spring Boot 主动调流媒体 API

Java 主动发起的操作都是"请求-响应"模式:发一个 HTTP 请求,同步拿回 JSON 结果。接口定义在 server/WebApi.cpp,常用的是这几个:

  • getMediaList:列出当前所有流
  • addStreamProxy:让服务器去拉一个外部源
  • delStreamProxy:停掉一路拉流代理
  • getThreadsLoad/getStatistic:线程负载与统计,做监控用

把最典型的拉流接口包成一个 Service,其他接口的调法和它一致:

@Service public class MediaService { @Value("${media.api.base}") private String apiBase; @Value("${media.secret}") private String secret; private final RestTemplate http = new RestTemplate(); // 让媒体服务器拉取外部源(rtsp/rtmp)并注册为本地流 public String pullStream(String stream, String url) { MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); form.add("secret", secret); form.add("stream", stream); form.add("url", url); return http.postForObject(apiBase + "/addStreamProxy", form, String.class); } }

请求体是普通表单参数,响应里code=0表示成功。需要完整字段说明时,看 www/swagger/openapi.json 这份 OpenAPI 文档,导入 swagger-ui 可以直接浏览。

异步回调:配置 WebHook 回调地址

另一个方向是"事件驱动":你不发请求,媒体服务器有事发生时就 POST 到你预先配置的地址。这种回调机制叫 WebHook,在 conf/config.ini 的hook.*下填地址即可启用:

[hook] enable=1 on_publish=http://127.0.0.1:8080/hook/on_publish on_play=http://127.0.0.1:8080/hook/on_play on_stream_changed=http://127.0.0.1:8080/hook/on_stream_changed

Hook 分两种。裁决型on_publishon_play:媒体服务器要等你的答复才继续,你必须回allow=1操作才能放行;通知型on_stream_changed:只需要收到并处理,不用做决策。一个裁决型接口长这样:

/** 媒体服务器接收 RTMP 推流前调用,返回 allow=1 表示放行 */ @PostMapping("/hook/on_publish") public Map<String, Object> onPublish(@RequestParam Map<String, String> req) { boolean allowed = authService.hasPublishRight(req.get("stream")); Map<String, Object> resp = new HashMap<>(); resp.put("code", 0); resp.put("allow", allowed ? 1 : 0); return resp; }

注意hook.timeoutSec(默认 10 秒):业务系统超时无应答会被判定为拒绝。所以鉴权逻辑要做得简单快速,发短信、记账单这类重活交给异步线程。

跟着一条直播流的完整生命周期走一遍

沿着一条叫streamA的流,把两个系统里实际发生的事理一遍 📺

第一步,推流。主播用推流软件推rtmp://你的域名/live/streamA。媒体服务器发现配置了on_publish,把这次推流的appstream、来源ip等字段 POST 给 Spring Boot,自己先暂停处理,等待答复。

第二步,鉴权。前面的on_publish接口去查库:推流者是否注册、时段是否合法。回allow=1后媒体服务器才正式收流。注意这里的边界:鉴权只是一次短命的 HTTP 请求,而推流本身是长连接的 RTMP 会话,两种交互模式在这里交汇。

第三步,注册上报。流建立后,媒体服务器触发on_stream_changedreg=1表示注册,reg=0表示销毁)。这个事件是流状态的唯一事实来源:Spring Boot 在此写库或写 Redis,前端的"直播中/已结束"标签也靠它刷新。

第四步,播放。观众在网页打开 HTTP-FLV 地址,或拿 m3u8 地址播 HLS。如果配了on_play,每次播放会先经过一次鉴权——挂计费逻辑的常见位置。还有个容易忽略的机制:maxStreamWaitMS(默认 15 秒)允许"先播放再推流",观众比主播早到页面不会立刻报错,会等流到位。

第五步,结束。推流断开,或拉流代理的流无人观看超过streamNoneReaderDelayMS(默认 20 秒),媒体服务器回调on_stream_changed(reg=0),业务侧据此做收尾。对拉流代理,还可以用on_stream_none_readerhook 自主决定关不关这路流。

把这条链路走通后能看清算法:媒体帧数据从不经过 Spring Boot,Java 层只接触元数据和决策。这正是这样拆分的意义——业务进程不用扛视频流的负载。

上生产之前必须处理的几件事

按严重程度和出问题的频率排一下序。

更换默认密钥。示例配置里的api.secret是公开的,知道它的人就能调用敏感接口增删流。上线前必改,并确保 Spring Boot 侧的media.secret与之同步。

让 hook 处理器幂等且快。hook 段里retry=1表示回调失败会重试一次,叠加网络抖动,同一个事件可能到达多次。on_stream_changed这类状态写入要做幂等处理;裁决型接口必须在timeoutSec内返回,超时就当拒绝。

给 RestTemplate 配上连接池和超时。默认的单机连接、无限等待在生产环境很脆,下面这份配置可直接套用:

@Bean public RestTemplate restTemplate() { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory( HttpClientBuilder.create() .setMaxConnTotal(100) .setMaxConnPerRoute(20).build()); factory.setConnectTimeout(3000); factory.setReadTimeout(10000); return new RestTemplate(factory); }

警惕状态不一致的坑。生产上最常见的现象是"前端显示直播中,实际已经结束了"。根源几乎都是前端状态没有以on_stream_changed事件为准,而是隔一段时间查一次库。让事件成为状态的单一来源,能消掉大部分此类问题。

定时任务盯住负载。周期调getThreadsLoadgetStatistic,前者返回各线程的 CPU 占用,后者返回在线流与协议统计,配一条阈值告警,比等用户报障早得多。排查 hook 行为异常时,把apiDebug=1打开,媒体服务器侧会打印每次 API 调用的内容和回复。

接下来可以继续探索的方向

"推流、播放、鉴权、状态"这条主线走通之后,可以按业务形态继续挖:

  • WebRTC 低延迟播放:完整的 DTLS/ICE/SRTP 协议栈实现在 webrtc/ 目录,接上后浏览器端可以拿到亚秒级延迟
  • GB28181 安防对接:接收国标监控设备流的 SIP/RTP 处理在 src/Rtp/,适合监控回传场景
  • SRT 传输:面向专线和大带宽场景的私有传输协议,实现见 srt/
  • 集群与多机部署:配置文件的cluster段支持源站按需拉流,适合源站与边缘节点分离的架构
  • 非 Java 语言接入:api/ 下封装了 C 接口,其他语言的服务可以用同样的方式控制媒体服务器

动手调试时,tests/ 目录里的示例代码覆盖了 HTTP 客户端、WebRTC 回归等场景,照着改比从零写快得多。协议细节和部署方式的权威说明,看项目根的 README.md 以及 conf/readme.md。

【免费下载链接】ZLMediaKitWebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framework based on C++11项目地址: https://gitcode.com/GitHub_Trending/zl/ZLMediaKit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 10:30:37

TVBoxOSC:给电视盒子装一个每天自动更新的 TVBox 播放器

TVBoxOSC&#xff1a;给电视盒子装一个每天自动更新的 TVBox 播放器 【免费下载链接】TVBoxOSC TVBoxOSC - 一个基于第三方项目的代码库&#xff0c;用于电视盒子的控制和管理。 项目地址: https://gitcode.com/GitHub_Trending/tv/TVBoxOSC TVBoxOSC 是一个面向 Androi…

作者头像 李华
网站建设 2026/9/10 10:29:21

Flutter跨平台化学学习应用开发与鸿蒙适配实践

1. 项目背景与核心价值 化学元素与方程式学习一直是初高中理科教育的重点难点。传统纸质教材存在互动性差、记忆效率低等问题&#xff0c;而市面上多数学习类APP又往往功能单一、平台受限。我们团队基于Flutter框架开发的这款跨平台应用&#xff0c;首次实现了在鸿蒙系统上的原…

作者头像 李华
网站建设 2026/9/10 10:28:03

香港寡佬证公证要几个工作日?2026全新攻略,证天下快速申请步骤

香港寡佬证公证常规办理周期为5个工作日左右&#xff0c;具体时长会受材料完整程度、文书使用目的地影响。很多香港居民想要在内地办事&#xff0c;都会接触到这项公证业务&#xff0c;但不少人不清楚办理规则&#xff0c;下面整理 2026 实用办理指南&#xff0c;帮大家少走弯路…

作者头像 李华
网站建设 2026/9/10 10:26:34

FastAPI-Users 实战指南:异步认证、RBAC 权限与生产配置

简介&#xff1a;本资源是一个基于FastAPI-Users的轻量级用户管理系统实战示例&#xff0c;面向Python后端开发者及FastAPI初学者&#xff0c;解决RESTful API场景下快速集成安全认证与权限管理的共性难题。压缩包共11个文件&#xff0c;含6个核心Python源码&#xff08;如main…

作者头像 李华
网站建设 2026/9/10 10:25:44

一站式AI论文写作软件选谁 适配自身需求才是最优解

AI论文写作软件核心用户群体分类AI论文写作软件核心用户分为国内本硕博学生、医护科研人员、高校教师、留学生四类&#xff0c;需求差异明显。当前学术写作场景下&#xff0c;不同群体的写作目标、规范要求、时间成本压力各不相同&#xff0c;匹配对应功能的工具可有效降低写作…

作者头像 李华