springboot+vue+ ffmpeg实现视频的拉流播放详解

 更新时间:2026年06月28日 09:46:49   作者:每日技术  
这段文章详细介绍了使用SpringBoot和FFmpeg实现RTSP流媒体转HLS的技术方案,涵盖了服务端配置、前端播放及常见问题解决方法,感兴趣的小伙伴可以了解下

浏览器无法直接播放 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 自动处理。

四、常见问题排查

问题原因与解决
播放器 404HLS 目录未被 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视频播放的资料请关注脚本之家其它相关文章!

相关文章

  • 详细了解JAVA NIO之Buffer(缓冲区)

    详细了解JAVA NIO之Buffer(缓冲区)

    这篇文章主要介绍了JAVA NIO之Buffer(缓冲区)的相关资料,文中讲解非常细致,帮助大家更好的学习JAVA NIO,感兴趣的朋友可以了解下
    2020-07-07
  • IDEA2020.1使用LeetCode插件运行并调试本地样例的方法详解

    IDEA2020.1使用LeetCode插件运行并调试本地样例的方法详解

    这篇文章主要介绍了IDEA2020.1使用LeetCode插件运行并调试本地样例的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-09-09
  • 全面解读Java中的枚举类型enum的使用

    全面解读Java中的枚举类型enum的使用

    这篇文章主要介绍了Java中的枚举类型enum的使用,开始之前先讲解了枚举的用处,然后还举了枚举在操作数据库时的实例,需要的朋友可以参考下
    2016-04-04
  • springboot实现单、多文件上传过程(前后端都有)

    springboot实现单、多文件上传过程(前后端都有)

    Spring Boot中实现文件上传,前端使用`file`类型的`input`表单,后端通过`MultipartFile`类接收文件,上传接口接收`MultipartFile`参数,调用其方法处理文件,单文件上传直接处理,多文件上传需遍历`MultipartFile`数组
    2025-12-12
  • java批量采集豌豆荚网站Android应用图标和包名

    java批量采集豌豆荚网站Android应用图标和包名

    这篇文章主要介绍了java批量采集豌豆荚网站Android应用图标和包名,主要用在做主题时替换这些常见应用的图片,需要的朋友可以参考下
    2014-06-06
  • springboot对象为null的属性在json中不显示的解决

    springboot对象为null的属性在json中不显示的解决

    这篇文章主要介绍了springboot对象为null的属性在json中不显示的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • MybatisPlus使用idworker解决雪花算法重复

    MybatisPlus使用idworker解决雪花算法重复

    本文主要介绍了MybatisPlus使用idworker解决雪花算法重复,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • springboot 拦截器执行两次的解决方案

    springboot 拦截器执行两次的解决方案

    这篇文章主要介绍了springboot 拦截器执行两次的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java中的==、equals与hashCode区别与联系最佳实践

    Java中的==、equals与hashCode区别与联系最佳实践

    在Java开发中,==、equals和hashCode是三个高频出现的概念,也是初学者最容易混淆的知识点,本文将从底层原理出发,全面解析三者的区别、联系及最佳实践,帮你彻底理清它们的使用场景,感兴趣的朋友一起看看吧
    2025-09-09
  • SpringMVC框架如何与Junit整合看这个就够了

    SpringMVC框架如何与Junit整合看这个就够了

    这篇文章主要介绍了SpringMVC框架如何与Junit整合看这个就够了,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05

最新评论