30 分钟搞定 SpringBoot 视频推拉流!实战避坑指南
off999 2025-09-19 01:09 39 浏览 0 评论
30 分钟搞定 SpringBoot 视频推拉流!实战避坑指南
在音视频开发领域,SpringBoot 凭借其快速开发特性,成为很多开发者实现视频推拉流功能的首选框架。但实际开发中,从环境搭建到流处理优化,处处都可能遇到 “坑”。本文将从实战角度出发,带大家一步步搭建 SpringBoot 视频推拉流系统,解决常见问题,让你快速上手音视频开发。
一、先搞懂:视频推拉流核心概念
在动手开发前,必须先理清几个关键概念,避免后续开发 “一头雾水”。视频推拉流简单来说,就是 “推流端” 将视频数据传输到 “流媒体服务器”,“拉流端” 从服务器获取视频数据并播放的过程。其中,流媒体服务器是核心枢纽,负责接收、转码、分发视频流;常用的协议有 RTMP、HLS、RTSP,不同协议适用场景不同 ——RTMP 延迟低(1-3 秒),适合直播互动;HLS 基于 HTTP,兼容性强(支持浏览器、手机),但延迟较高(10-30 秒);RTSP 多用于安防监控设备。
而 SpringBoot 在这套体系中,主要负责 “胶水工作”:整合流媒体服务器、处理业务逻辑(如用户认证、流权限控制)、提供 API 接口供前端调用。比如,我们可以用 SpringBoot 开发一个 “直播房间管理” 功能,用户创建房间后,系统自动分配推流地址,观众进入房间时自动获取拉流地址,整个过程通过 SpringBoot 的接口完成交互。
二、实战第一步:环境搭建与依赖配置
1. 选择合适的流媒体服务器
实战中,不建议重复造轮子开发流媒体服务器,推荐使用成熟的开源方案。这里我们选SRS(Simple RTMP Server) ,它轻量、高性能,支持 RTMP、HLS、HTTP-FLV 等协议,且有完善的中文文档,对国内开发者友好。
SRS 的安装很简单(以 Linux 为例):
bash
# 克隆源码
git clone https://github.com/ossrs/srs.git
# 进入目录编译
cd srs/trunk && ./configure && make
# 启动服务器(默认端口1935,RTMP协议)
./objs/srs -c conf/srs.conf
启动后,通过telnet 127.0.0.1 1935能连接成功,说明 SRS 已正常运行。
2. SpringBoot 项目依赖配置
创建一个 SpringBoot 项目(推荐 2.x 版本,兼容性更稳定),在pom.xml中引入核心依赖:
- Spring Web:提供 HTTP 接口,用于前后端交互;
- FFmpeg 相关依赖:处理视频转码(如 RTMP 转 HLS,适配浏览器播放);
- Lombok:简化代码,减少 getter/setter;
- Spring Security(可选):用于推流 / 拉流权限控制。
关键依赖代码如下:
xml
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- FFmpeg工具类 -->
<dependency>
<groupId>com.github.kokorin.jaffree</groupId>
<artifactId>jaffree</artifactId>
<version>1.5.11</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
三、核心功能开发:从推流到拉流全流程
1. 推流端实现:用 FFmpeg 模拟推流
实际项目中,推流端可能是手机 APP、PC 客户端(如 OBS),但开发阶段我们可以用 FFmpeg 命令模拟推流,快速验证流程。
首先,准备一个测试视频文件(如test.mp4),执行以下命令将视频推送到 SRS 服务器:
bash
# 格式:ffmpeg -re -i 视频文件 -c:v libx264 -c:a aac -f flv rtmp://SRS服务器IP:1935/live/房间号
ffmpeg -re -i test.mp4 -c:v libx264 -c:a aac -f flv rtmp://192.168.1.100:1935/live/room123
其中,-re表示按视频实际帧率推流(避免推流过快),live是 SRS 配置的 “应用名”(对应srs.conf中的vhost __defaultVhost__下的app live),room123是 “流名”(可理解为直播房间 ID,需唯一)。
如果想通过 SpringBoot 接口触发推流(比如自动推流监控视频),可以封装 FFmpeg 工具类,通过 Java 代码调用 FFmpeg 命令:
java
@Slf4j
@Component
public class FFmpegUtil {
// 推流方法:输入文件路径、SRS推流地址
public void pushStream(String inputPath, String rtmpUrl) {
try {
// 构建FFmpeg命令
FFmpeg.atPath()
.addArgument("-re")
.addArgument("-i")
.addArgument(inputPath)
.addArgument("-c:v")
.addArgument("libx264")
.addArgument("-c:a")
.addArgument("aac")
.addArgument("-f")
.addArgument("flv")
.addArgument(rtmpUrl)
.execute();
log.info("推流成功,推流地址:{}", rtmpUrl);
} catch (Exception e) {
log.error("推流失败:{}", e.getMessage());
throw new RuntimeException("推流异常", e);
}
}
}
2. 拉流端实现:多端适配(PC / 手机 / 浏览器)
拉流端需要适配不同设备,这里分两种场景实现:
(1)RTMP 拉流(适合 PC 客户端,如 VLC)
直接使用推流地址的 RTMP 链接,在 VLC 播放器中 “打开网络串流”,输入
rtmp://192.168.1.100:1935/live/room123,即可播放视频。
(2)HLS 拉流(适合浏览器 / 手机)
浏览器不支持 RTMP 协议,需要将 RTMP 流转成 HLS 流(生成.m3u8索引文件和.ts分片文件)。我们可以在 SRS 中配置自动转码,修改srs.conf:
conf
vhost __defaultVhost__ {
app live {
# 开启HLS转码
hls {
enabled on;
# HLS文件保存路径(需提前创建)
hls_path ./objs/nginx/html;
# 分片时长(默认10秒,越小延迟越低)
hls_fragment 5;
# 索引文件包含的分片数
hls_window 3;
}
}
}
重启 SRS 后,推流时会自动生成 HLS 文件,拉流地址为http://SRS服务器IP:8080/live/room123.m3u8(SRS 默认开启 8080 端口提供 HTTP 服务)。
在 SpringBoot 中,我们可以开发一个 “获取拉流地址” 的接口,根据设备类型返回不同协议的地址:
java
@RestController
@RequestMapping("/stream")
@RequiredArgsConstructor
public class StreamController {
private final String srsIp = "192.168.1.100";
// 获取拉流地址:deviceType=pc(RTMP)、mobile/browser(HLS)
@GetMapping("/pull")
public ResultVO getPullUrl(@RequestParam String roomId, @RequestParam String deviceType) {
String pullUrl;
if ("pc".equals(deviceType)) {
pullUrl = "rtmp://" + srsIp + ":1935/live/" + roomId;
} else {
pullUrl = "http://" + srsIp + ":8080/live/" + roomId + ".m3u8";
}
return ResultVO.success("拉流地址获取成功", pullUrl);
}
}
3. 权限控制:防止非法推流 / 拉流
没有权限控制的流很容易被 “盗用”,比如别人用你的推流地址推垃圾内容,或盗用你的直播流。我们可以用 Spring Security 实现简单的权限校验:
(1)推流权限校验
推流时,要求客户端携带 “认证令牌”,SpringBoot 接口验证令牌通过后,才返回有效的推流地址。
首先,生成推流令牌(可用 JWT):
java
@Component
public class JwtUtil {
private final String secret = "springboot-stream-secret"; // 密钥,实际项目需加密存储
// 生成推流令牌:包含房间号、过期时间(1小时)
public String generatePushToken(String roomId) {
return Jwts.builder()
.setSubject(roomId)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
// 验证令牌
public boolean validateToken(String token, String roomId) {
try {
Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
return roomId.equals(claims.getSubject()) && new Date().before(claims.getExpiration());
} catch (Exception e) {
return false;
}
}
}
然后,开发 “获取推流地址” 的接口,验证令牌后返回地址:
java
@PostMapping("/push")
public ResultVO getPushUrl(@RequestParam String roomId, @RequestParam String token) {
// 验证令牌
if (!jwtUtil.validateToken(token, roomId)) {
return ResultVO.error("令牌无效,无推流权限");
}
String pushUrl = "rtmp://" + srsIp + ":1935/live/" + roomId;
return ResultVO.success("推流地址获取成功", pushUrl);
}
(2)拉流权限校验
拉流时,SRS 支持 “回调校验”,即每次拉流前,SRS 会调用 SpringBoot 的校验接口,通过后才允许拉流。配置srs.conf:
conf
vhost __defaultVhost__ {
app live {
# 拉流回调校验
http_hooks {
enabled on;
# 校验接口地址
on_hls_play http://SpringBoot服务器IP:8081/stream/checkPull;
}
}
}
SpringBoot 中开发校验接口,比如验证用户是否已登录:
java
@PostMapping("/checkPull")
public void checkPull(HttpServletRequest request, HttpServletResponse response) throws IOException {
// SRS回调时会携带roomId(流名)、userId(可从请求参数获取,需客户端传递)
String roomId = request.getParameter("stream");
String userId = request.getParameter("userId");
// 模拟校验:用户是否已登录(实际项目查数据库/Redis)
boolean hasPermission = "user123".equals(userId);
// 校验通过返回200,失败返回403
if (hasPermission) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
四、实战避坑:这些问题 90% 的人都会遇到
1. 推流失败:连接超时 / 拒绝连接
- 原因 1:SRS 服务器未启动,或端口被占用(1935 端口常用,可能被其他程序占用)。
解决:用netstat -tuln | grep 1935查看端口占用,杀死占用进程后重启 SRS。 - 原因 2:防火墙未开放 1935(RTMP)、8080(HLS HTTP)端口。
解决:Linux 执行firewall-cmd --add-port=1935/tcp --permanent和firewall-cmd --add-port=8080/tcp --permanent,然后firewall-cmd --reload。
2. 拉流延迟过高(超过 30 秒)
- 原因:HLS 分片时长设置过大,或 SRS 缓存配置不合理。
解决:在srs.conf中减小hls_fragment(如设为 3 秒),同时开启 “低延迟模式”:
conf
hls {
enabled on;
hls_fragment 3;
hls_window 2;
# 开启低延迟
hls_low_latency on;
}3. 浏览器播放 HLS 流卡顿
- 原因:视频码率过高,浏览器加载分片慢;或分片文件未及时生成。
解决:推流时降低码率(FFmpeg 命令加-b:v 500k,表示视频码率 500kbps);同时确保 SRS 的hls_path目录有写入权限。
五、项目优化:从 “能用” 到 “好用”
1. 流状态监控
实时监控推流是否正常,避免 “推流断了但没人知道”。可以用 SRS 的 HTTP API 获取流状态,SpringBoot 定时调用接口:
java
@Component
@Scheduled(fixedRate = 5000) // 每5秒监控一次
public class StreamMonitor {
private final String srsApiUrl = "http://192.168.1.100:8080/api/v1/streams";
@Autowired
private RestTemplate restTemplate;
public void monitorStream() {
try {
String response = restTemplate.getForObject(srsApiUrl, String.class);
// 解析JSON,判断流是否存在(如room123是否在流列表中)
JSONObject json = new JSONObject(response);
JSONArray streams = json.getJSONArray("streams");
boolean isPushing = streams.stream()
.map(JSONObject.class::cast)
.anyMatch(s -> "live/room123".equals(s.getString("name")));
if (!isPushing) {
log.warn("房间room123推流已中断!");
// 发送告警(如短信、钉钉通知)
}
} catch (Exception e) {
log.error("流监控失败:{}", e.getMessage());
}
}
}
2. 集群部署(高并发场景)
当直播房间多、观众量大时,单台 SRS 服务器扛不住,需要集群部署。核心思路是:
- 用 Nginx 做负载均衡,分发推流 / 拉流请求;
- 多台 SRS 服务器通过 “集群同步”(如 SRS 的 RTMP Edge 模式)共享流数据;
- SpringBoot 服务集群部署,用 Redis 共享用户会话、流状态。
六、总结:快速上手的核心要点
- 先搭环境再开发:优先搞定 SRS 服务器,用 FFmpeg 模拟推流,验证基础流程;
- 协议选择看场景:低延迟用 RTMP,兼容性用 HLS;
- 权限控制不能少:用 JWT+SRS 回调防止非法访问;
- 遇到问题先查日志:SRS 日志(./objs/srs.log)和 SpringBoot 日志是排错关键。
按照本文的步骤,你可以在 1 小时内搭建一个能跑通的 SpringBoot 视频推拉流系统,后续再根据业务需求(如直播带货、在线教育)扩展功能(如弹幕、连麦)。如果在开发中遇到具体问题,欢迎在评论区交流!
感谢关注【AI码力】!
相关推荐
- 浏览器最好用的(浏览器最好用的插件)
-
一、谷歌浏览器谷歌浏览器是公认最好用的,这个可以从市场占有率看出端倪,超过三分之二的用户使用谷歌浏览器。Chrome浏览器以简洁快速著称,不管是普通用户还是开发人员,chrome浏览器都是首选。Chr...
- fast路由器6位初始密码(fast路由器的密码)
-
答:fast路由器初始密码是admin;新款的迅捷无线路由器,管理界面没有初始密码。查看迅捷无线路由器底部标签,标签上标注了admin,说明初始密码就是admin;如果没有,说明该路由器没有初始密码。...
- 硬盘恢复软件哪个好(硬盘 恢复软件)
-
迷你兔数据恢复工具:支持恢复硬盘丢失的数据Pc3000数据恢复软件是一款非常专业的硬盘修复工具,能够对电脑硬盘资料数据进行修复,通过使用这个软件可以解决硬盘数据丢失故障,是一个用户进行硬盘资料修复好帮...
- 十大品牌监控摄像头排名(十大品牌监控摄像头排名第一)
-
答:1、华为/HUAWEI9.92、小米/MI9.63、罗技/Logitech9.64、海康威视/HIKVISION9.25、乔安/Jooan9.26、普联/TP-LINK9.27、乐橙8.98、萤石...
- 360手机助手老旧版本大全(360手机助手 老版本)
-
在设置里面找到历史记录就可能查看360手机助手·换机神器是安卓系统的换机软件,因为苹果的换机软件是爱思。1、打开360手机卫士,登陆账号,点击账号。2、进入个人中心,点击账户安全,在密保工具中,点击解...
- 系统应用工程师(系统工程的应用)
-
信息软件系统工程师有前途,毕业以后可以从事软件开发,软件系统的维护,运营等等,和计算机有关的工作内容,因为计算机专业可以说是一个非常热门的专业,很多的大型企业公司基本上都是以计算机研发为主的,薪资福利...
- qq恢复系统常见问题(qq恢复系统常见问题及答案)
-
QQ好友恢复系统一直显示服务器频繁有可能是系统的问题,你的qq重新更新一下,或者你卸载了重新下载一下就有可能好了。您好,很高兴为您解答:您可以试试清空下IE内存,然后关掉不必要的程序,尽量在电脑运...
- win10自带的office不见了(win10自带的office在哪个文件夹)
-
win10系统的office在电脑硬盘office的安装目录里,具体打开安装目录的操作如下:1、首先我们右键点击word,打开方式,选择默认程序打开。2、在默认框打钩,点击【浏览】。3、打开你安装of...
- w10系统我的电脑在哪里(windows10 我的电脑在哪)
-
首先,打开Windows10系统,可以看到当前桌面上没有“我的电脑”。二、然后,在桌面上鼠标右键都加空白处,在右键菜单中选择“个性化”,点击打开。三、然后,在窗口中左侧选择“更改桌面图标”,点击打开。...
- 2500电脑组装最强配置(2500左右组装电脑主机配置清单)
-
两千五百元组装电脑,但配置只能是一般。台式机分为主机和显示器两个主体,按这个价格,显示器只能配置一般的,大约两百多元价格,其余都用来组装主机,主机包含机箱,电源,排风扇,电脑主板及内存,电脑处理器,声...
-
- 小米手机定时关机怎么设置(如何让小米手机定时关机)
-
1、从设置菜单中找到电池与性能选项。 2、选择电池版块,点击定时开关机。 3、将定时开机右边的按钮开...
-
2025-12-28 02:51 off999
- 磁盘删除的文件怎么恢复(磁盘误删怎么恢复)
-
可以恢复,因为删除文件时,其实只是把表头删除了,后面的数据并没有删除,直到下一次进行写磁盘操作需要占用节点所在位置时,才会把相应的数据覆盖掉。所以,就算你误删了文件之后又进行了其他写磁盘操作,只要没有...
-
- qq自动回复内容古风(qq自动回复古文)
-
1、抽剑相助,搭救无辜,却引来杀身之祸。那女子故作柔弱,假装爱慕,只为那本剑谱。2、只缘感君一回顾,使我思君朝与暮。3、相知相惜若可谓缘,不负韶华年。4、看那天地日月,恒静无言;青山长河,世代绵延;就像在我心中,你从未离去,也从未改变。5、...
-
2025-12-28 01:51 off999
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
