news 2026/5/30 22:07:00

从监控室到浏览器:用SpringBoot和Vue3,5步搭建一个轻量级海康威视视频监控Web平台

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从监控室到浏览器:用SpringBoot和Vue3,5步搭建一个轻量级海康威视视频监控Web平台

从监控室到浏览器:用SpringBoot和Vue3构建企业级视频监控平台

在数字化转型浪潮中,视频监控系统正从传统的封闭式架构向基于Web的智能平台演进。本文将带您从零搭建一个支持多画面布局、设备管理和权限控制的企业级监控解决方案,采用SpringBoot 3.x与Vue 3的组合技术栈,实现前后端分离的高效开发模式。

1. 项目架构设计与环境准备

现代监控平台需要兼顾实时性、扩展性和安全性。我们采用分层架构设计:

  • 前端层:Vue 3 + TypeScript + Pinia状态管理
  • 网关层:Spring Cloud Gateway实现API路由
  • 服务层:SpringBoot 3.x + JDK 17
  • 流媒体层:FFmpeg转码集群
  • 存储层:MinIO对象存储

技术选型对比表:

组件选型方案优势
前端框架Vue 3组合式API更适合复杂交互
协议支持WebSocket+RTSP低延迟与广泛兼容
安全认证JWT+OAuth2双重保障
部署方式Docker Compose一键环境初始化
# 初始化SpringBoot项目 spring init --dependencies=web,security,data-jpa \ --build=gradle \ --java-version=17 \ monitor-platform-backend

2. 后端核心服务实现

2.1 设备管理模块

采用DDD领域驱动设计,核心领域模型包括:

@Entity public class CameraDevice { @Id private String deviceId; @Enumerated(EnumType.STRING) private DeviceStatus status; @Embedded private NetworkConfig network; @OneToMany(mappedBy = "device") private Set<VideoChannel> channels; } @Embeddable public class NetworkConfig { private String ipAddress; private Integer rtspPort; private String authUsername; private String authPassword; }

设备状态同步采用定时任务与事件驱动结合:

@Scheduled(fixedRate = 30000) public void syncDeviceStatus() { deviceRepository.findAll().forEach(device -> { DeviceStatus newStatus = hikvisionClient.checkStatus(device); if(device.getStatus() != newStatus) { eventPublisher.publishEvent(new DeviceStatusChangedEvent(device)); } }); }

2.2 视频流服务封装

流媒体处理核心流程:

  1. RTSP源流获取
  2. FFmpeg实时转码为HLS
  3. 自适应码率处理
  4. 边缘节点分发
public class StreamConvertService { private static final String FFMPEG_CMD = "ffmpeg -i %s -c:v libx264 -preset ultrafast " + "-hls_time 2 -hls_list_size 3 -hls_flags delete_segments %s"; public String startConvert(String rtspUrl) { String outputPath = generateHlsPath(); String command = String.format(FFMPEG_CMD, rtspUrl, outputPath); Process process = Runtime.getRuntime().exec(command); registerProcess(process, outputPath); return getPlayUrl(outputPath); } }

注意:生产环境建议使用MediaServer等专业流媒体服务器替代直接调用FFmpeg

3. 前端交互设计与实现

3.1 动态布局管理系统

采用响应式栅格系统实现1x1到4x4的多画面布局:

<script setup lang="ts"> const layoutModes = [ { cols: 1, rows: 1 }, { cols: 2, rows: 2 }, { cols: 3, rows: 2 } ] as const; const currentLayout = ref<LayoutMode>('1x1'); function changeLayout(mode: LayoutMode) { const config = layoutModes.find(m => `${m.cols}x${m.rows}` === mode); gridSystem.reconfigure(config); } </script> <template> <div class="layout-controls"> <button v-for="mode in ['1x1', '2x2', '3x2']" @click="changeLayout(mode)" :class="{ active: currentLayout === mode }" > {{ mode }} </button> </div> <div class="video-grid" :style="gridStyle"> <VideoCell v-for="cell in gridCells" :key="cell.id" :stream="cell.stream" /> </div> </template>

3.2 实时视频组件封装

基于Web Components封装播放器:

class HikVideoPlayer extends HTMLElement { private videoElement: HTMLVideoElement; constructor() { super(); this.attachShadow({ mode: 'open' }); this.videoElement = document.createElement('video'); this.shadowRoot!.append(this.videoElement); } async playStream(url: string) { try { if (this.videoElement.canPlayType('application/vnd.apple.mpegurl')) { // 原生HLS支持 this.videoElement.src = url; } else { // MSE回退方案 await loadHlsJsLibrary(); const hls = new Hls(); hls.loadSource(url); hls.attachMedia(this.videoElement); } await this.videoElement.play(); } catch (error) { console.error('播放失败:', error); } } } customElements.define('hik-video', HikVideoPlayer);

4. 平台进阶功能实现

4.1 视频快照与录像管理

后端存储服务设计:

public interface StorageService { String storeSnapshot(InputStream imageStream, String deviceId); String startRecording(String streamId); void stopRecording(String taskId); List<Recording> queryRecordings(String deviceId, LocalDateTime start, LocalDateTime end); } @RestController @RequestMapping("/api/recordings") public class RecordingController { @PostMapping("/{deviceId}/snapshot") public ResponseEntity<SnapshotResult> takeSnapshot( @PathVariable String deviceId, @RequestParam(required = false) String quality) { Stream stream = streamService.getByDevice(deviceId); byte[] image = hikvisionClient.captureSnapshot(stream.getRtspUrl()); String url = storageService.storeSnapshot( new ByteArrayInputStream(image), deviceId ); return ResponseEntity.ok(new SnapshotResult(url)); } }

前端操作界面实现:

<template> <div class="toolbar"> <button @click="takeSnapshot" title="截图"> <CameraIcon /> </button> <button @click="toggleRecording" :class="{ recording: isRecording }" title="录像" > <RecordIcon /> </button> <TimeRangePicker v-model="playbackTime" @change="loadPlayback" /> </div> </template> <script setup> const takeSnapshot = async () => { const result = await fetch(`/api/recordings/${deviceId}/snapshot`); // 显示截图结果 }; </script>

4.2 权限与设备分组

基于RBAC的权限模型设计:

CREATE TABLE user_group ( id BIGINT PRIMARY KEY, name VARCHAR(50) NOT NULL ); CREATE TABLE device_group ( id BIGINT PRIMARY KEY, name VARCHAR(50) NOT NULL ); CREATE TABLE group_permission ( user_group_id BIGINT, device_group_id BIGINT, can_view BOOLEAN DEFAULT false, can_control BOOLEAN DEFAULT false, PRIMARY KEY (user_group_id, device_group_id) );

前端权限校验逻辑:

function usePermission() { const { user } = useAuthStore(); const checkPermission = (deviceId: string, action: 'view' | 'control') => { return user.groups.some(group => group.permissions.some(p => p.deviceGroup.devices.includes(deviceId) && (action === 'view' ? p.canView : p.canControl) ) ); }; return { checkPermission }; }

5. 性能优化与生产部署

5.1 前端性能调优

实施策略:

  • 视频流懒加载
  • WebWorker处理解码
  • 虚拟滚动长列表

优化前后对比数据:

指标优化前优化后
首屏加��4.2s1.8s
内存占用320MB180MB
CPU使用率65%38%

5.2 后端高可用方案

集群部署架构:

[Nginx LB] / | \ [Gateway集群] [流媒体集群] [业务服务集群] | | [Redis哨兵] [MySQL集群]

Docker Compose配置示例:

version: '3.8' services: gateway: image: openjdk:17-jdk ports: - "8080:8080" deploy: replicas: 3 depends_on: - redis - config-server media-server: image: nginx-rtmp ports: - "1935:1935" volumes: - ./media:/var/media deploy: resources: limits: cpus: '2' memory: 2G

在项目上线后,我们通过Prometheus+Grafana构建的监控体系发现,采用HTTP/3协议传输视频元数据可降低约40%的延迟。对于需要接入第三方摄像头的场景,建议在流媒体层增加ONVIF协议转换模块

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 22:00:43

RecyclerBanner 开源项目教程

RecyclerBanner 开源项目教程 【免费下载链接】RecyclerBanner 用RecyclerView实现无限轮播图&#xff0c;有普通版和3d版 项目地址: https://gitcode.com/gh_mirrors/re/RecyclerBanner 项目介绍 RecyclerBanner 是一个基于 RecyclerView 实现的无尽轮播图控件。它允许…

作者头像 李华
网站建设 2026/5/30 22:00:01

告别黑屏花屏!在 Ubuntu 上为 xrdp 配置 XFCE 轻量桌面的完整避坑实践

告别黑屏花屏&#xff01;在 Ubuntu 上为 xrdp 配置 XFCE 轻量桌面的完整避坑实践远程桌面连接是管理无显示器服务器的常见需求&#xff0c;但许多用户在 Ubuntu 上配置 xrdp 时都会遇到黑屏或花屏问题。本文将分享一套经过实战验证的配置方案&#xff0c;特别适合资源有限的 A…

作者头像 李华
网站建设 2026/5/30 21:54:14

程序员这个行业是不是不行了?

今年对程序员来说是极不友好的一年&#xff0c;像往年这个时间段一般是程序员跳槽涨薪的黄金期&#xff0c;是很多程序员集体往大厂冲刺的时间段&#xff1b;但由于各大厂纷纷裁员&#xff0c;整得整个互联网行业人心惶惶&#xff0c;纷纷质疑&#xff1a;大厂还值得去吗&#…

作者头像 李华