Spring Boot + Vue + ZLMediaKit 实现 RTSP 拉流播放的完整方案

以下是基于 Spring Boot + Vue + ZLMediaKit 实现 RTSP 拉流播放的完整方案,包含架构设计、关键代码和注意事项:


一、系统架构设计

scss 复制代码
graph TD
    A[摄像头/RTSP源] -->|RTSP协议| B(Spring Boot 后端)
    B -->|RTMP/HTTP-FLV协议| C(ZLMediaKit流媒体服务器)
    C -->|HLS/HTTP-FLV协议| D(Vue前端播放器)
  1. ​后端层​:Spring Boot 负责接收 RTSP 流并推送到 ZLMediaKit
  2. ​流媒体层​:ZLMediaKit 完成协议转换和流分发
  3. ​前端层​:Vue 通过播放器库渲染视频流

二、环境准备

  1. ​ZLMediaKit 部署​

    bash 复制代码
    # Docker 部署(推荐)
    docker run -d --name zlmediakit \
      -p 1935:1935 \  # RTMP
      -p 8080:80 \   # HTTP
      -p 554:554 \   # RTSP
      -v /opt/media:/opt/media \
      zlmediakit/zlmediakit:master
  2. ​Spring Boot 项目依赖​

    xml 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.lunasaw</groupId>
        <artifactId>zlm-spring-boot-starter</artifactId>
        <version>1.0.0</version>
    </dependency>

三、核心实现步骤

1. 后端流媒体服务配置(Spring Boot)

yaml 复制代码
# application.yml
zlm:
  api:
    url: http://localhost:9092  # ZLMediaKit管理地址
    secret: your_secret_key      # 流媒体鉴权密钥
  media:
    ip: 0.0.0.0                # 监听所有IP
    rtsp-port: 554             # RTSP服务端口
    rtmp-port: 1935            # RTMP服务端口

2. RTSP 流推送服务

less 复制代码
@RestController
public class StreamController {
    
    @Autowired
    private ZLMediaKitService zlmService;

    // 添加流代理
    @PostMapping("/addStreamProxy")
    public ResponseEntity<String> addStreamProxy(@RequestBody StreamRequest request) {
        String url = String.format("http://%s:%d/index/api/addStreamProxy?"
                + "vhost=%s&app=live&stream=%s&url=%s&secret=%s",
                zlmService.getZlmIp(), zlmService.getZlmPort(),
                request.getVhost(), request.getApp(), request.getStreamId(),
                URLEncoder.encode(request.getRtspUrl(), StandardCharsets.UTF_8),
                zlmService.getZlmSecret());
        
        // 调用 ZLMediaKit API
        String response = zlmService.executeCommand(url);
        return ResponseEntity.ok(response);
    }
}

3. 数据库设计(MySQL)

sql 复制代码
CREATE TABLE stream_config (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    camera_name VARCHAR(255) COMMENT '摄像头名称',
    rtsp_url VARCHAR(512) NOT NULL COMMENT 'RTSP地址',
    stream_id VARCHAR(64) UNIQUE COMMENT '流ID',
    status TINYINT DEFAULT 0 COMMENT '流状态'
);

四、前端播放实现(Vue)

1. 播放器组件

xml 复制代码
<template>
  <div>
    <video ref="player" controls autoplay muted></video>
  </div>
</template>

<script>
import flvjs from 'flv.js';

export default {
  props: ['streamUrl'],
  mounted() {
    this.initPlayer();
  },
  methods: {
    initPlayer() {
      if (flvjs.isSupported()) {
        const videoElement = this.$refs.player;
        const flvPlayer = flvjs.createPlayer({
          type: 'flv',
          url: this.streamUrl
        });
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load();
        flvPlayer.play();
      }
    }
  }
}
</script>

2. 流地址获取接口

ini 复制代码
// 获取流地址接口示例
axios.get('/api/stream/info', { params: { cameraId: 1 } })
  .then(response => {
    const flvUrl = `http://${response.data.ip}:${response.data.port}/${response.data.app}/${response.data.stream}.flv`;
    this.playStream(flvUrl);
  });

五、关键配置说明

  1. ​ZLMediaKit 转码配置​

    ini 复制代码
    # config.ini
    [ffmpeg]
    cmd=ffmpeg -re -i %s -c:v libx264 -preset ultrafast -tune zerolatency -f flv %s
  2. ​Spring Boot 控制台日志​

    ini 复制代码
    logging.level.com.lunasaw.zlm=DEBUG

六、常见问题解决方案

问题现象 解决方案
流无法推送 检查 ZLMediaKit 控制台是否开启 RTSP 服务,确认防火墙端口开放
播放卡顿 调整 FFmpeg 转码参数,增加 -b:v 2000k 提升码率
音视频不同步 添加 -vsync 1 -async 1 参数优化同步
多路流管理 使用 ZLMediaKit 的流组功能进行批量管理

七、性能优化建议

  1. ​硬件加速​:启用 GPU 编码(如 NVIDIA NVENC)
  2. ​集群部署​:通过 ZLMediaKit 的集群模式实现负载均衡
  3. ​缓存策略​:使用 Redis 缓存流元数据,减少数据库查询
  4. ​CDN 分发​:对 HLS 流启用 CDN 加速

八、扩展功能实现

  1. ​流状态监控​

    kotlin 复制代码
    @ZlmHook
    public class StreamMonitor {
        @Override
        public Response streamStarted(StreamInfo info) {
            // 记录流启动日志
            return super.streamStarted(info);
        }
    }
  2. ​动态码率切换​

    javascript 复制代码
    // 前端切换码率示例
    const hls = new Hls();
    hls.loadSource('http://example.com/stream.m3u8');
    hls.on(Hls.Events.LEVEL_SWITCHED, (event, data) => {
      console.log('当前码率:', data.level);
    });

通过上述方案,可以实现完整的 RTSP 拉流播放系统。建议先通过 Docker 快速部署 ZLMediaKit,再逐步集成 Spring Boot 业务逻辑。实际开发中需注意网络传输优化和异常处理机制。

相关推荐
道可到7 小时前
Java 反射现代实践速查表(JDK 11+/17+)
java
道可到7 小时前
Java 反射现代实践指南(JDK 11+ / 17+ 适用)
java
艾小码8 小时前
Vue组件到底怎么定义?全局注册和局部注册,我踩过的坑你别再踩了!
前端·javascript·vue.js
玉衡子8 小时前
九、MySQL配置参数优化总结
java·mysql
叽哥8 小时前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin
麦兜*8 小时前
MongoDB Atlas 云数据库实战:从零搭建全球多节点集群
java·数据库·spring boot·mongodb·spring·spring cloud
带刺的坐椅8 小时前
DamiBus v1.1.0 发布(给单体多模块解耦)
java·事件总线·damibus
葡萄城技术团队8 小时前
用 Java 构建健壮 REST API 的 4 个关键技巧
java
杨杨杨大侠8 小时前
解密 atlas-mapper 框架 (9/10):故障排查与调试技巧
java·开源·github
Slaughter信仰8 小时前
深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十章知识点问答(10题)
java·jvm·数据库