從 0 到 1,帶你用 SpringBoot 打造專屬視頻推流系統!
在實際項目中,視頻推流和拉流功能是常見的需求場景,例如遠程監控、無人機實時畫面、在線直播等。最初,我打算通過 Netty 自己實現一套 RTSP 協議的推拉流服務,但在處理 RTSP 解包時遇到了較大瓶頸,自研難度超出了預期。
后來發現了一個更優雅的解決方案 —— Zlm4j。它是基于 ZLMediaKit 封裝的 JNA 接口,能夠非常方便地與 SpringBoot 集成,省去了大量底層處理的工作。這里也特別感謝 ZLMediaKit 與 Zlm4j 的開源貢獻者們,使我們能夠快速落地視頻流服務。
本文將結合代碼,詳細展示如何在 SpringBoot 中搭建一個輕量的推拉流系統,并完成推流測試、播放驗證,最后補充一個基于 Thymeleaf + Bootstrap 的前端播放頁面,幫助大家在實際開發中快速實現類似需求。
代碼集成步驟
引入依賴
項目的核心依賴是 zlm4j 與 jna:
- zlm4j:對 ZLMediaKit 的封裝庫,直接調用核心 API;
- jna:負責底層調用 ZLMediaKit 的 SDK,不需要單獨安裝 ZLMediaKit 服務。
pom.xml 配置如下:
<dependency>
<groupId>com.aizuda</groupId>
<artifactId>zlm4j</artifactId>
<version>1.0.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/zlm4j-1.0.4.jar</systemPath>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.14.0</version>
</dependency>
<!-- Thymeleaf 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Web 模塊 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>配置類
在 SpringBoot 中創建一個配置類,負責:
- 初始化 ZLMApi;
- 開啟 HTTP/RTSP/RTMP/RTP 服務;
- 注冊 事件監聽器(MK_EVENTS)。
代碼如下:
package com.icoderoad.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;
@Configuration
public class ZlmServerConfig {
@Bean
public ZLMApi zlmApi() {
// 加載 mk_api 庫
ZLMApi zlmApi = Native.load("mk_api", ZLMApi.class);
// 初始化 SDK 環境
zlmApi.mk_env_init1(1, 1, 1, null, 0, 0, null, 0, null, null);
// 啟動 HTTP 服務
zlmApi.mk_http_server_start((short) 7788, 0);
// 啟動 RTSP 服務
zlmApi.mk_rtsp_server_start((short) 9758, 0);
// 啟動 RTMP 服務
zlmApi.mk_rtmp_server_start((short) 9759, 0);
// 啟動 RTP 服務
zlmApi.mk_rtp_server_start((short) 32000);
return zlmApi;
}
@Bean
public MK_EVENTS mkEvents() {
return new MK_EVENTS();
}
}配置的服務端口如下:
協議 | 端口 |
HTTP | 7788 |
RTSP | 9758 |
RTMP | 9759 |
RTP | 32000 |
事件實現
在啟動類中,通過 CommandLineRunner 注冊事件監聽,完成:
- 推流鑒權:驗證客戶端是否有權限推流;
- 流狀態變化:監控流的上線/下線。
代碼示例:
package com.icoderoad;
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;
@SpringBootApplication
public class VideoStreamApplication implements CommandLineRunner {
@Autowired
private MK_EVENTS mkEvents;
@Autowired
private ZLMApi zlmApi;
public static void main(String[] args) {
SpringApplication.run(VideoStreamApplication.class, args);
}
@Override
public void run(String... args) {
// 推流鑒權事件
mkEvents.on_mk_media_publish = (url_info, invoker, sender) -> {
String params = zlmApi.mk_media_info_get_params(url_info);
System.out.println("鑒權參數:" + params);
zlmApi.mk_publish_auth_invoker_do(invoker, "", 0, 0);
};
zlmApi.mk_events_listen(mkEvents);
// 流狀態變化事件
mkEvents.on_mk_media_changed = (regist, sender) -> {
System.out.println("App: " + zlmApi.mk_media_source_get_app(sender));
System.out.println("Stream: " + zlmApi.mk_media_source_get_stream(sender));
System.out.println("Schema: " + zlmApi.mk_media_source_get_schema(sender));
System.out.println("流狀態改變通知: " + regist);
};
zlmApi.mk_events_listen(mkEvents);
}
}推流與播放測試
推流命令
通過 FFmpeg 將本地視頻推送到 RTSP 服務端口,并攜帶鑒權參數:
ffmpeg -re -an -i /home/user/videos/input.mp4 -c:v libx264 -f rtsp rtsp://127.0.0.1:9758/stream/1?token=112233事件輸出
控制臺會打印:
- 鑒權參數(例如 token 值);
- 流狀態改變通知(上線/下線)。
播放驗證
使用 VLC 播放器打開推流的 RTMP 地址即可播放:
rtmp://127.0.0.1:9759/stream/1也可以選擇 HTTP-FLV、HLS、WebRTC 等其他協議進行播放。
前端播放頁面(Thymeleaf + Bootstrap)
為了讓系統更直觀,我們可以在瀏覽器中播放推流視頻。
控制器
創建一個簡單的 Controller,返回播放頁面:
package com.icoderoad.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class PlayerController {
@GetMapping("/player")
public String player(Model model) {
// 傳遞推流地址(RTMP/HTTP-FLV/HLS均可)
model.addAttribute("videoUrl", "http://127.0.0.1:7788/live/stream.flv");
return "player";
}
}頁面模板
<!--src/main/resources/templates/player.html-->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>視頻播放</title>
<link rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js"></script>
</head>
<body class="bg-light">
<div class="container mt-5">
<h3 class="text-center mb-4">實時視頻播放</h3>
<div class="card shadow rounded-3">
<div class="card-body">
<video id="videoElement" class="w-100 rounded-3" controls></video>
</div>
</div>
</div>
<script th:inline="javascript">
let videoUrl = [[${videoUrl}]];
if (flvjs.isSupported()) {
let videoElement = document.getElementById('videoElement');
let flvPlayer = flvjs.createPlayer({
type: 'flv',
url: videoUrl
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html>這里用到了 flv.js 播放 HTTP-FLV 視頻流,同時配合 Bootstrap 做了頁面美化。
總結
通過以上步驟,我們在 SpringBoot 項目中快速集成了 Zlm4j,實現了一個輕量的視頻推拉流系統,并且提供了前端可視化播放頁面:
- 后端:
- 依賴配置簡潔,直接調用 zlm4j;
- 配置類快速啟動多協議服務;
- 事件監聽支持鑒權與流狀態回調。
- 前端:
- 基于 Thymeleaf + Bootstrap;
- 使用 flv.js 播放視頻流;
- 頁面簡潔美觀,支持擴展。
這種方式不僅降低了開發成本,還能快速應用到實際項目中,未來也可以擴展錄制、轉碼、直播間管理等功能。如果你正在尋找一個高效的視頻推拉流解決方案,那么基于 SpringBoot + Zlm4j + Thymeleaf 的組合無疑是一個非常實用的選擇。


































