在智慧安防、在线教育直播、户外设备实时回传等实际项目中,视频推拉流是核心基础能力。最初我尝试基于 Netty 手动封装 RTSP 协议实现服务 —— 既要处理 RTSP 的信令交互,又要解决视频帧解包的时序同步问题,实际开发中不仅遇到解包效率低的瓶颈,还出现了不同设备兼容性差的问题,自研成本远超预期。
后来偶然发现Zlm4j这个工具:它是基于高性能流媒体框架 ZLMediaKit 封装的 JNA 接口,能直接与 SpringBoot 无缝集成,省去了底层协议解析、端口管理等繁琐工作。特别感谢 ZLMediaKit 与 Zlm4j 的开源团队,让我们不用重复造轮子,快速落地流媒体服务。
本文将结合完整代码,一步步教你在 SpringBoot 中搭建可直接复用的视频推拉流系统,涵盖推流鉴权、多协议播放、前端可视化页面,帮助你跳过 “踩坑环节”,直接对接实际业务需求。
核心实现步骤
第一步:引入关键依赖
项目核心依赖围绕 Zlm4j 展开,同时搭配 Web 模块与 Thymeleaf 模板引擎(用于前端页面),无需单独安装 ZLMediaKit 服务,JNA 会自动处理底层调用。
pom.xml配置如下:
<!-- Zlm4j:封装ZLMediaKit核心能力 --><dependency><groupId>com.aizuda</groupId><artifactId>zlm4j</artifactId><version>1.0.5</version><scope>system</scope><systemPath>${project.basedir}/lib/zlm4j-1.0.5.jar</systemPath></dependency><!-- JNA:处理底层SDK调用 --><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.15.0</version></dependency><!-- SpringBoot Web:提供HTTP服务 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Thymeleaf:前端页面渲染 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
第二步:编写配置类,启动多协议服务
创建配置类ZlmStreamConfig,核心作用是初始化 ZLMediaKit 环境、启动 HTTP/RTSP/RTMP/RTP 等主流流媒体协议服务,同时注册事件监听载体。
代码示例:
package com.stream.config;import com.aizuda.zlm4j.core.ZLMApi;import com.aizuda.zlm4j.structure.MK_EVENTS;import com.sun.jna.Native;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ZlmStreamConfig {/*** 初始化ZLMApi,启动多协议服务*/@Beanpublic ZLMApi zlmApi() {// 加载ZLMediaKit核心库ZLMApi zlmApi = Native.load("mk_api", ZLMApi.class);// 初始化SDK环境:日志开启、后台运行、默认配置zlmApi.mk_env_init1(1, 1, 1, null, 0, 0, null, 0, null, null);// 启动各协议服务(端口可根据业务调整)zlmApi.mk_http_server_start((short) 7789, 0); // HTTP服务:用于FLV/HLS播放zlmApi.mk_rtsp_server_start((short) 9758, 0); // RTSP服务:常用于设备推流zlmApi.mk_rtmp_server_start((short) 9760, 0); // RTMP服务:常用于直播平台zlmApi.mk_rtp_server_start((short) 32001); // RTP服务:用于实时媒体传输return zlmApi;}/*** 注册事件监听载体:处理推流鉴权、流状态变化等事件*/@Beanpublic MK_EVENTS mkEvents() {return new MK_EVENTS();}}
各协议端口说明如下:
| 协议 | 端口 | 用途 |
|---|---|---|
| HTTP | 7789 | 提供 HTTP-FLV、HLS 格式视频播放 |
| RTSP | 9758 | 接收设备(如摄像头)推流 |
| RTMP | 9760 | 接收直播推流、支持播放器播放 |
| RTP | 32001 | 低延迟实时媒体数据传输 |
第三步:实现事件监听,保障服务安全
在 SpringBoot 启动类中实现CommandLineRunner接口,注册推流鉴权和流状态监控事件 —— 前者防止非法推流,后者实时感知流的上线 / 下线,方便排查问题。https://wxa.wxs.qq.com/tmpl/oc/base_tmpl.html

代码示例:
package com.stream;import com.aizuda.zlm4j.core.ZLMApi;import com.aizuda.zlm4j.structure.MK_EVENTS;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import java.util.Date;@SpringBootApplicationpublic class VideoStreamApp implements CommandLineRunner {@Autowiredprivate MK_EVENTS mkEvents;@Autowiredprivate ZLMApi zlmApi;public static void main(String[] args) {SpringApplication.run(VideoStreamApp.class, args);}@Overridepublic void run(String... args) {// 1. 推流鉴权事件:验证推流请求合法性mkEvents.on_mk_media_publish = (urlInfo, invoker, sender) -> {// 获取推流携带的鉴权参数(如token)String authParams = zlmApi.mk_media_info_get_params(urlInfo);System.out.println("[" + new Date() + "] 推流鉴权参数:" + authParams);// 实际业务中可校验token:合法则允许推流(0表示通过),非法则拒绝boolean isAuthPass = authParams.contains("token=stream2025");zlmApi.mk_publish_auth_invoker_do(invoker, "", isAuthPass ? 0 : 1, 0);};zlmApi.mk_events_listen(mkEvents);// 2. 流状态变化事件:监控流的上线/下线mkEvents.on_mk_media_changed = (isOnline, sender) -> {String appName = zlmApi.mk_media_source_get_app(sender);String streamName = zlmApi.mk_media_source_get_stream(sender);String protocol = zlmApi.mk_media_source_get_schema(sender);String status = isOnline == 1 ? "上线" : "下线";System.out.println("[" + new Date() + "] 流状态变化:" + protocol + "://" + appName + "/" + streamName + " " + status);};zlmApi.mk_events_listen(mkEvents);}}
推拉流测试:验证链路通畅
1. 推流操作(基于 FFmpeg)
使用 FFmpeg 工具将本地视频文件推送到 RTSP 服务端口,同时携带鉴权 token(需与鉴权逻辑匹配)。
打开终端执行命令:
# -re:按视频实际速率推流;-an:不传输音频;-c:v libx264:使用H.264视频编码ffmpeg -re -an -i /Users/test/videos/demo.mp4 -c:v libx264 -f rtsp rtsp://127.0.0.1:9758/live/demo?token=stream2025
2. 控制台事件输出
推流成功后,控制台会打印鉴权信息和流上线通知:
[Wed Sep 05 08:30:00 CST 2025] 推流鉴权参数:token=stream2025[Wed Sep 05 08:30:01 CST 2025] 流状态变化:rtsp://live/demo 上线
3. 播放验证(多播放器支持)
- VLC 播放器打开 “媒体”→“打开网络串流”,输入 RTMP 地址
rtmp://127.0.0.1:9760/live/demo,点击播放即可观看。 - PotPlayer输入 HTTP-FLV 地址
http://127.0.0.1:7789/live/demo.flv,支持更低延迟播放。
前端播放页面:可视化交互
为了让业务方更方便地使用,我们基于Thymeleaf+Bootstrap+flv.js开发前端页面,支持浏览器直接播放视频。
第一步:编写控制器(跳转页面)
创建StreamPlayerController,传递视频播放地址到前端:
package com.stream.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.GetMapping;@Controllerpublic class StreamPlayerController {/*** 跳转视频播放页面*/@GetMapping("/stream/player")public String toPlayerPage(Model model) {// 传递HTTP-FLV播放地址(浏览器兼容性更好)String flvUrl = "http://127.0.0.1:7789/live/demo.flv";model.addAttribute("videoUrl", flvUrl);return "stream-player";}}
第二步:开发前端页面(stream-player.html)
页面采用 Bootstrap 美化布局,使用 flv.js 处理 FLV 格式视频,同时增加播放状态提示:
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>实时视频播放平台</title><!-- 引入Bootstrap样式 --><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"><!-- 引入flv.js:处理FLV视频流 --><script src="https://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js"></script></head><body class="bg-gray-100"><div class="container mt-6"><!-- 页面标题 --><div class="text-center mb-5"><h2 class="text-primary">实时视频播放</h2><p class="text-muted" id="playStatus">等待推流连接...</p></div><!-- 视频播放区域 --><div class="card shadow rounded-4"><div class="card-body p-0"><video id="streamPlayer" class="w-100 rounded-top-4" controls autoplay></video><div class="p-3 bg-light"><p class="mb-0"><span class="fw-bold">播放地址:</span><span th:text="${videoUrl}"></span></p></div></div></div></div><script th:inline="javascript">// 获取后端传递的视频地址const videoUrl = [[${videoUrl}]];const videoElement = document.getElementById('streamPlayer');const statusElement = document.getElementById('playStatus');// 初始化flv播放器if (flvjs.isSupported()) {const flvPlayer = flvjs.createPlayer({type: 'flv',url: videoUrl,isLive: true // 标记为直播流,优化延迟});// 绑定视频元素flvPlayer.attachMediaElement(videoElement);// 加载并播放flvPlayer.load();flvPlayer.play().then(() => {statusElement.textContent = "播放中(低延迟模式)";statusElement.className = "text-success fw-medium";}).catch(error => {statusElement.textContent = "播放失败:" + error.message;statusElement.className = "text-danger";});// 监听播放错误flvPlayer.on('error', (err) => {statusElement.textContent = "播放异常:" + err;statusElement.className = "text-danger";});// 监听流断开flvPlayer.on('stats', (stats) => {if (stats.bufferedLength === 0 && !flvPlayer.isPlaying()) {statusElement.textContent = "流已断开,请检查推流服务";statusElement.className = "text-warning";}});} else {statusElement.textContent = "当前浏览器不支持FLV播放,请更换Chrome/Firefox";statusElement.className = "text-danger";}</script></body></html>
访问页面
启动SpringBoot 项目后,在浏览器输入
http://127.0.0.1:8080/stream/player,即可看到视频播放页面 —— 推流正常时会自动播放,同时显示实时状态。
系统总结与扩展方向
核心优势
- 后端轻量高效基于 Zlm4j 封装,无需关注底层协议,几行配置即可启动多协议服务;
- 安全可控支持推流鉴权,防止非法接入;流状态监控便于问题排查;
- 前端易用浏览器直接播放,无需安装额外插件,适配主流浏览器;
- 兼容性强支持 RTSP/RTMP/HTTP-FLV/HLS 等多种协议,可对接摄像头、直播软件等不同设备。
扩展方向
- 视频录制集成 ZLMediaKit 的录制接口,实现 “推流即录制”,支持按时间切片存储;
- 多房间管理基于 Redis 存储流信息,实现多用户同时观看不同流,支持房间权限控制;
- 转码功能添加 FFmpeg 转码服务,自动将视频转为多种分辨率(如 720P/480P),适配不同网络环境;
- 告警通知对流断开、推流超时等异常情况,通过短信 / 邮件发送告警,提升运维效率
微信扫描下方的二维码阅读本文

Comments NOTHING