vue+flv.js+SpringBoot+websocket实现视频监控与回放功能

一、前言

本文将介绍如何利用Vue.js、flv.js、SpringBoot和Websocket来实现简易的视频监控与回放功能。我们将会用到flv.js来进行视频的播放,SpringBoot作为后端框架,使用Websocket实现双向通信,将用户的操作传输到服务端处理并返回相应的结果。

二、环境搭建

在开始项目之前,我们需要先进行环境搭建。

1.前端环境:

  • Vue.js
  • Vue Router
  • Element UI
  • Axios
  • flv.js

2.后端环境:

  • JDK8+
  • Maven
  • SpringBoot
  • SpringWebsocket
  • Redis

三、项目搭建

1.前端项目搭建

首先,我们需要创建一个Vue项目。在创建项目的时候,需要选择一些基础配置,例如项目名称、项目描述、作者等信息。随后我们要安装依赖并引入需要的插件和组件。我们在这里需要引入Vue Router、Element UI和Axios。

安装路由:

npm install vue-router

在main.js里面引入:

import VueRouter from 'vue-router';
import router from './router';//引入自己的路由文件

Vue.use(VueRouter);

安装Element UI:

npm install element-ui -S

安装axios:

npm i axios

之后在main.js里面引入:

import axios from 'axios';
import VueAxios from 'vue-axios';

Vue.use(VueAxios, axios);

安装flv.js:

npm install flv.js -S

2.后端项目搭建

我们使用Maven来创建新的SpringBoot项目。首先我们需要在pom.xml文件里添加SpringBoot、WebSocket和Redis的依赖,并添加flv.js所需要的CORS跨域配置。

添加依赖:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
</dependencies>

添加Cors配置:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT");
    }
}

四、具体实现

1.监控操作界面

在我们的Vue页面中,我们需要实现两个监控界面,一个是直播监控、一个是回放监控。我们可以通过不同的url来控制界面展示。

在vue的App.vue导航栏中我们需要添加两个按钮:实时监控和回放录像,点击按钮后跳转到对应的界面。

<template>
  <div id="app">
    <el-header class="header">
      <el-menu :default-active="activeIndex" mode="horizontal" @select="selectItem">
        <el-menu-item index="1"><router-link to="/">实时监控</router-link></el-menu-item>
        <el-menu-item index="2"><router-link to="/player">回放录像</router-link></el-menu-item>
      </el-menu>
    </el-header>

    <router-view></router-view>
  </div>
</template>

我们再来看一下两个界面的配置:

<template>
  <div class="container">
    <el-row>
      <el-col :span="16">
        <div class="video-container">
          <video :id="roomId" ref="videoPlayer" class="video-player"></video>
        </div>
      </el-col>

      <el-col :span="8">
        <div class="control-panel">
          <el-form ref="form" :model="form" label-position="top">
            <el-form-item v-if="!hideStartButton">
              <el-button type="primary" :loading="loading" class="control-btn" @click="start">开始</el-button>
            </el-form-item>

            <el-form-item v-if="!hideStopButton">
              <el-button type="danger" class="control-btn" @click="stop">结束</el-button>
            </el-form-item>

            <el-form-item>
              <el-input placeholder="请输入房间号" v-model="form.roomId"></el-input>
            </el-form-item>
          </el-form>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

这里我们使用了Element UI组件来搭建我们的监控面板,包括视频播放器、控制面板和表单模块。其中视频播放器引用了flv.js库。通过这些组件,我们可以轻松地搭建一个视频监控的前端界面。

2.监控实现

前端界面差不多搭好以后,我们就大可以开始实现视频监控功能了。

在前端的vue文件中,我们需要定义一些数据和控制变量,供我们的监控界面使用。

除此之外,我们还需要引入flv.js库,并利用它来构建我们的监控视频播放器。

<template>
  <div class="container">
    <el-row>
      <el-col :span="16">
        <div class="video-container">
          <video :id="roomId" ref="videoPlayer" class="video-player"></video>
        </div>
      </el-col>

      <el-col :span="8">
        <div class="control-panel">
          <el-form ref="form" :model="form" label-position="top">
            <el-form-item>
              <el-button type="primary" @click="start">开始</el-button>
            </el-form-item>
            <el-form-item>
              <el-button type="danger" @click="stop">结束</el-button>
            </el-form-item>
            <el-form-item>
              <el-input placeholder="请输入房间号" v-model="form.roomId"></el-input>
            </el-form-item>
          </el-form>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

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

export default {
  data() {
    return {
      roomId: '',
      form: {
        roomId: ''
      },
      loading: false,
      hideStartButton: false,
      hideStopButton: true,
      socket: null,           // websocket对象
      flvPlayer: null,        // flv.js播放器对象
      flvConfig: null,        // flv.js配置
      flvPath: null           // flv.js播放地址
    }
  },
  methods: {
    start() {
      if (!this.form.roomId) {
        this.$message.error('请输入房间号');
        return;
      }

      this.hideStartButton = true;
      this.hideStopButton = false;
      this.loading = true;

      this.getWebSocket();    // 获取websocket对象
      this.initFlvPlayer();   // 初始化flv.js播放器
    },
    stop() {
      this.hideStartButton = false;
      this.hideStopButton = true;

      this.socket.close();   // 关闭 websocket 链接
      this.flvPlayer.pause(); // 暂停 flv.js 播放器
      this.flvPlayer.unload(); // 卸载 flv.js 播放器
      this.flvPlayer.detachMediaElement(); // 停止 flv.js 播放元素
      this.flvPlayer.destroy(); // 销毁 flv.js 播放器
      this.flvPlayer = null;
      this.flvConfig = null;
      this.flvPath = null;
    },
    getWebSocket() {
      this.socket = new WebSocket(`ws://localhost:8888/test?roomId=${this.form.roomId}`);

      this.socket.onopen = () => {
        console.log('连接服务器成功');
      };

      this.socket.onmessage = (event) => {
        const result = JSON.parse(event.data);
        console.log(`获取到消息:${result}`);

        if (result && result.code === 0 && result.data) {
          this.flvPath = result.data;
          console.log(`获取到flv.js播放地址:${this.flvPath}`);
          this.initFlvPlayer()
        }
      };

      this.socket.onclose = () => {
        console.log('与服务器断开连接');
      };

      this.socket.onerror = (event) => {
        console.log(`连接服务器出错:${event}`);
      }
    },
    initFlvPlayer() {
      console.log('初始化 flv.js 播放器');

      if (!flvjs.isSupported()) {
        console.log('您的浏览器不支持flv.js');
        return;
      }

      if (this.flvPlayer) {
        this.flvPlayer.load();
        return;
      }

      this.flvConfig = {
        type: 'flv',
        url: `${this.flvPath}?token=${localStorage.getItem('token')}`
      };

      this.flvPlayer = flvjs.createPlayer(this.flvConfig);
      this.flvPlayer.attachMediaElement(this.$refs.videoPlayer);
      this.flvPlayer.load();
      this.flvPlayer.play();
    }
  }
}
</script>

在这里,我们实现了start()方法、stop()方法、getWebSocket()方法、initFlvPlayer()方法,以及一些用于控制前端的变量。

我们结合flv.js和WebSocket来实现了实时监控的功能,包括获取WebSocket对象、初始化flv.js播放器和启动flv.js应用程序等。我们通过WebSocket来从服务器获取flv路径,然后通过flv.js播放容器来获取实时监控视频。

3.回放实现

在回放监控端,我们需要进一步进行代码编写。首先,我们需要在Vue组件中引用新的Element UI组件,并通过Element UI来搭建新的监控面板。

我们还需要在Vue组件中定义一些新的变量、对象和方法,尤其是从后端服务器获取历史视频数据,以及使用flv.js播放历史视频数据。

<template>
  <div class="container">
    <el-row>
      <el-col :span="16">
        <div class="video-container">
          <video :id="roomId" ref="videoPlayer" class="video-player"></video>
        </div>
      </el-col>

      <el-col :span="8">
        <div class="control-panel">
          <el-form ref="form" :model="form" label-position="top">
            <el-form-item>
              <el-date-picker v-model="startTime" type="datetime"></el-date-picker>
            </el-form-item>
            <el-form-item>
              <el-date-picker v-model="endTime" type="datetime"></el-date-picker>
            </el-form-item>
            <el-form-item>
              <el-input placeholder="请输入房间号" v-model="form.roomId"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="search">查询</el-button>
            </el-form-item>
          </el-form>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

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

export default {
  data() {
    return {
      roomId: '',
      form: {
          roomId: '',
      },
      startTime: '',
      endTime: '',
      hideSearchButton: false,
      socket: null,
      flvPlayer: null,
      flvConfig: null,
      flvPath: null
    }
  },
  methods: {
    search() {
      if (!this.form.roomId) {
        this.$message.error('请输入房间号');
        return;
      }

      if (!this.startTime || !this.endTime) {
        this.$message.error('请选择开始时间和结束时间');
        return;
      }

      const start = Math.floor(this.startTime.getTime() / 1000);
      const end = Math.floor(this.endTime.getTime() / 1000);

      if (start >= end) {
        this.$message.error('开始时间不能大于等于结束时间');
        return;
      }

      this.hideSearchButton = true;

      axios.get(`http://localhost:8080/video/hls/${this.form.roomId}?startTime=${start}&endTime=${end}`, {}).then(res => {
        console.log(res);

        if (res.data.code === 0) {
          this.flvPath = res.data.data;
          console.log(`获取到flv.js播放地址:${this.flvPath}`);
          this.initFlvPlayer()
        }
      }).catch(error => {
        console.log(error);
      });
    },
    initFlvPlayer() {
      console.log('初始化 flv.js 播放器');

      if (!flvjs.isSupported()) {
        console.log('您的浏览器不支持flv.js');
        return;
      }

      if (this.flvPlayer) {
        this.flvPlayer.load();
        return;
      }

      this.flvConfig = {
        type: 'flv',
        url: `${this.flvPath}?token=${localStorage.getItem('token')}`
      };

      this.flvPlayer = flvjs.createPlayer(this.flvConfig);
      this.flvPlayer.attachMediaElement(this.$refs.videoPlayer);
      this.flvPlayer.load();
      this.flvPlayer.play();
    }
  }
}
</script>

在这里,我们同时展示了如何使用Axios获取历史视频数据,以及如何将返回的数据使用flv.js播放器来播放。

五、示例

下面是两个我搭建的跑通的项目例子和相关代码:

  1. 实时监控:https://github.com/AndyShentu/vue-flv-socket-demo

  2. 回放监控:https://github.com/AndyShentu/vue-flv-player-demo

以上是本文对“Vue+flv.js+SpringBoot+websocket实现视频监控与回放功能”的完整攻略,如果你有任何问题,欢迎反馈!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue+flv.js+SpringBoot+websocket实现视频监控与回放功能 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • jQuery UI对话框resizeStop()事件

    以下是关于 jQuery UI 对话框 resizeStop() 事件的详细攻略: jQuery UI 对话框 resizeStop() 事件 resizeStop() 事件是在用户停止调整对话框大小时触发的事件。可以使用该事件来执行一些操作,例如保存对话框的大小或位置。 语法 $(selector).dialog({ resizeStop: functio…

    jquery 2023年5月11日
    00
  • jQWidgets jqxGauge LinearGauge valueChanged事件

    jQWidgets jqxGauge LinearGauge valueChanged事件 jQWidgets是一个基于jQuery的UI组件库,提供了丰富的UI组件和工具,包括表格、表、历、菜单等。jqxGauge和jqxLinearGauge是jQWidgets中的两个组件,用于显示仪盘和线性仪盘。这两个组件都提供了valueChanged事件用于在值发…

    jquery 2023年5月9日
    00
  • jQWidgets jqxNotification autoOpen属性

    以下是关于 jQWidgets jqxNotification 组件中 autoOpen 属性的详细攻略。 jQWidgets jqxNotification autoOpen 属性 jQWidgets jqxNotification 的 autoOpen 属性用于设置通知组件是否自动打开。 语法 // 设置通知组件是否自动打开 $(‘#notificati…

    jquery 2023年5月12日
    00
  • jQWidgets jqxGrid deferreddatafields属性

    以下是关于“jQWidgets jqxGrid deferreddatafields属性”的完整攻略,包含两个示例说明: 简介 jqxGrid 控件的 deferreddatafields 属性用于在数据加载延迟加载某些,以提高性能。 完整攻略 以下是 jqxGrid 控件 deferreddatafields 属性的完攻略: 定义deferreddataf…

    jquery 2023年5月11日
    00
  • jQWidgets jqxDropDownList clearSelection()方法

    jQWidgets jqxDropDownList clearSelection()方法详解 jQWidgets是一个基于jQuery的UI组件库,提供了丰富UI组件和工具包。jqxDropDownList是Widgets组件现下组件。本文将详细介绍jqxDropDownList的clearSelection()方法,包括用语法和示例。 clearSelec…

    jquery 2023年5月10日
    00
  • jQuery对象[0]是什么含义?

    jQuery对象[0]的含义是将一个JQuery集合中的第一个元素转换为原生DOM元素。 一般情况下,我们可以使用.get(index)方法获取集合中指定的元素,例如: let $elements = $(‘.example’); // 获取所有class为example的元素 let firstElement = $elements.get(0); // …

    jquery 2023年5月28日
    00
  • jQWidgets jqxMaskedInput高度属性

    jQWidgets jqxMaskedInput高度属性详解 jQWidgets是一个基于jQuery的UI组件库,提供了丰富UI组件工具包。jqxMaskedInput是其中之一。本文将详细介绍jqMaskedInput的height属性,包括用法、语法和示例。 height属性的语法 jqxMaskedInput的height属性用于设置输入框的高度。基…

    jquery 2023年5月10日
    00
  • JQuery查找子元素find()和遍历集合each的方法总结

    JQuery查找子元素find()和遍历集合each的方法总结 在开发前端网页时,使用jQuery可以方便地处理DOM元素。其中,查找子元素和遍历集合是经常用到的操作。本文主要讲解jQuery中的find()方法和each()方法的使用。 一、JQuery find()方法 1.1 find()方法概览 jQuery中的find()方法可以根据选择器查找匹配…

    jquery 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部