springboot+vue+ ffmpeg实现视频的拉流播放详解
浏览器无法直接播放 RTSP/RTMP 等监控流协议,典型做法是:Spring Boot 调用服务器上安装的 FFmpeg,把拉到的流转成 HLS(.m3u8+.ts),Spring Boot 静态资源暴露地址,Vue 前端用 video.js 或 hls.js 播放。下面给你完整可落地的示例。
一、整体架构
摄像头RTSP → FFmpeg(转HLS) → 输出目录(/hls/xxx.m3u8 + .ts)
↑
Spring Boot ProcessBuilder 启动/停止
↓
Spring Boot 静态资源映射 → http://ip:port/hls/xxx.m3u8
↓
Vue + video.js / hls.js 播放 HLS
建议生产环境用 Nginx 托管 HLS 目录并做跨域,Spring Boot 只负责启停 FFmpeg 进程和接口。
二、服务端 — Spring Boot 调用 FFmpeg
1. FFmpeg 转 HLS 核心命令
ffmpeg -rtsp_transport tcp \ -i "rtsp://admin:密码@192.168.1.100:554/stream1" \ -c:v libx264 -preset ultrafast -tune zerolatency \ -c:a aac \ -f hls \ -hls_time 2 \ -hls_list_size 5 \ -hls_flags delete_segments \ -hls_segment_filename "/opt/hls/stream_%03d.ts" \ /opt/hls/stream.m3u8
-rtsp_transport tcp:比 UDP 稳定,防花屏hls_time 2:每片 2 秒,延迟约 4~8 秒属正常delete_segments:自动删旧切片防磁盘爆满
2. FFmpeg 服务类(启停进程)
@Service
public class FfmpegService {
private Process ffmpegProcess;
private static final String HLS_DIR = "/opt/hls/";
// Windows 改成 "C:\\ffmpeg\\bin\\ffmpeg.exe"
public synchronized void startStream(String rtspUrl) throws IOException {
stopStream(); // 先停旧进程
new File(HLS_DIR).mkdirs();
List<String> cmd = new ArrayList<>();
cmd.add("ffmpeg");
cmd.addAll(List.of("-rtsp_transport", "tcp"));
cmd.addAll(List.of("-i", rtspUrl));
cmd.addAll(List.of("-c:v", "libx264", "-preset", "ultrafast", "-tune", "zerolatency"));
cmd.addAll(List.of("-c:a", "aac"));
cmd.addAll(List.of("-f", "hls", "-hls_time", "2", "-hls_list_size", "5"));
cmd.addAll(List.of("-hls_flags", "delete_segments"));
cmd.addAll(List.of("-hls_segment_filename", HLS_DIR + "stream_%03d.ts"));
cmd.add(HLS_DIR + "stream.m3u8");
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
ffmpegProcess = pb.start();
// 异步消费 FFmpeg 输出,防止阻塞
new Thread(() -> {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(ffmpegProcess.getInputStream()))) {
while (br.readLine() != null) {}
} catch (IOException ignored) {}
}).start();
}
public synchronized void stopStream() {
if (ffmpegProcess != null && ffmpegProcess.isAlive()) {
ffmpegProcess.destroyForcibly();
}
}
}
3. Controller + 静态资源映射
@RestController
@RequestMapping("/api/stream")
public class StreamController {
@Autowired
private FfmpegService ffmpegService;
@PostMapping("/start")
public String start(@RequestParam String rtsp) throws IOException {
ffmpegService.startStream(rtsp);
return "started";
}
@PostMapping("/stop")
public String stop() {
ffmpegService.stopStream();
return "stopped";
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问 http://ip:8080/hls/stream.m3u8
registry.addResourceHandler("/hls/**")
.addResourceLocations("file:/opt/hls/");
}
}
三、前端 — Vue 播放 HLS
安装依赖
npm install video.js hls.js
Vue 3 组件示例
<template>
<div>
<video ref="videoEl" id="my-video" class="video-js vjs-default-skin"
controls width="800" height="450">
</video>
<button @click="play">开始播放</button>
</div>
</template>
<script setup>
import { ref, onBeforeUnmount } from 'vue'
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
const videoEl = ref(null)
let player = null
const play = () => {
if (player) player.dispose()
player = videojs(videoEl.value, {
sources: [{
src: 'http://localhost:8080/hls/stream.m3u8',
type: 'application/x-mpegURL'
}]
})
}
onBeforeUnmount(() => {
player?.dispose()
})
</script>Safari 原生支持 HLS,Chrome/Firefox 靠 video.js 内部集成 hls.js 自动处理。
四、常见问题排查
| 问题 | 原因与解决 |
|---|---|
| 播放器 404 | HLS 目录未被 Spring 静态资源映射或 Nginx 未配 alias |
| 能下载 m3u8 但播不出 | .ts 切片路径不对,确认 segment_filename 在同一目录 |
| 花屏/断流 | RTSP 改用 -rtsp_transport tcp,检查网络 |
| 多路流 CPU 飙高 | FFmpeg 转码耗 CPU,可用 -c:v copy(不重编码,需源流 H.264+AAC)或用 ZLMediaKit/SRS 替代 |
| CORS 报错 | Spring Boot 加 CORS 或 Nginx 加 Access-Control-Allow-Origin * |
五、进阶建议
轻量场景:上述 FFmpeg + Spring Boot 够用
多路监控/低延迟:推荐用 ZLMediaKit 或 **SRS(Simple Realtime Server)** 做流媒体服务器,Spring Boot 只做信令控制,Vue 播放 HTTP-FLV 或 WebRTC,延迟可压到 1 秒内
以上就是springboot+vue+ ffmpeg实现视频的拉流播放详解的详细内容,更多关于springboot vue视频播放的资料请关注脚本之家其它相关文章!
相关文章
IDEA2020.1使用LeetCode插件运行并调试本地样例的方法详解
这篇文章主要介绍了IDEA2020.1使用LeetCode插件运行并调试本地样例的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧2020-09-09
springboot对象为null的属性在json中不显示的解决
这篇文章主要介绍了springboot对象为null的属性在json中不显示的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-09-09
Java中的==、equals与hashCode区别与联系最佳实践
在Java开发中,==、equals和hashCode是三个高频出现的概念,也是初学者最容易混淆的知识点,本文将从底层原理出发,全面解析三者的区别、联系及最佳实践,帮你彻底理清它们的使用场景,感兴趣的朋友一起看看吧2025-09-09


最新评论