vue前端对接监控视频 FLV格式 (分屏的操作 单屏 ,四平 ,六屏)

系列文章目录

vue前端对接监控视频 FLV格式


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

西瓜视频

  • 系列文章目录
  • 前言
  • 一、准备工作
        • 下好以后在 package.json 检查一下
  • 二、引入到index的文件当中
    • 1.引入库、介绍
    • 2.开始绘制页面
      • 定义的变量
      • css样式
    • 三核心代码的书写
    • ` 到此也就结束,使用代码片段的时候需要将图片替换一下不然会出现路径的问题`


前言

接触智慧园区,智慧工地,水泵站等项目之后,发现都有实时监控的对接,并且是可以多屏进行,就研究了相关的技术栈,找到了这个强大的播放器对前端还是很友好的,话不多说上干货!!!


提示:代码片段里有博主对的接口,读代码的时候注意

一、准备工作

1. 使用npm 、cnpm、yarn 下载如下插件  
2. npm install xgplayer
3. npm install xgplayer-flv
4. npm install xgplayer-flv.js
下好以后在 package.json 检查一下

在这里插入图片描述

二、引入到index的文件当中

1.引入库、介绍

代码如下(示例):

import Player from "xgplayer"; // 这是他的一个方法
import FlvPlayer from "xgplayer-flv"; // 这个是搭配上面哪个使用的
import 'xgplayer/dist/index.min.css' // 这个是播放器的样式 ,可以在当前页面使用,也可以放全局let a = new Player({id: this.playList[0].id,// 对应 isLive: true,	 // 是否是直播,plugins: [FlvPlayer], // 视频播放的方式url: '你的视屏地址', // 地址autoplay: true, // lang: "zh-cn", // 是否自动播放,autoplayMuted: true,//是否自动静音自动播放screenShot: true, //是否使用截图插件rotate:false,//是否使用旋转插件download:false,//是否使下载按钮pip:false,//是否使用画中画插件mini:false,//是否启用mini小窗插件playbackRate:[0.5, 0.75, 1, 1.5, 2],//倍速插件显示列表});

2.开始绘制页面

提示 :这里用到了Element-ui的tree组件,还有博主自己写一些样式就直接拿过来的 取自己用的即可
代码如下(示例):

<template><div class="list"><div class="lsieqqwe"><div class="boseList bgImg"><span@click="getall"style="color: #fff; margin-left: 12px; font-size: 16px">设备分组span>div><div style="padding: 5px"><el-inputv-model="deptName"placeholder="请输入部门名称"clearablesize="small"prefix-icon="el-icon-search"style="margin-bottom: 5px"/>div><div class="treeDataLsit"><el-treeclass="filter-tree":data="treeData"ref="tree":props="defaultProps"node-key="id"default-expand-all:expand-on-click-node="false"highlight-current@node-click="handleNodeClick":filter-node-method="filterNode"><span slot-scope="{ node, data }" class="customize-tree-p"><div class="haha" v-if="node.level == 3"><img:src="data.isOnline == 1? '/img/isOnlinetrue.png': '/img/isOnlinefalse.png'"alt=""/><span>{{ data.channelName }} span>div><span v-else>{{ data.channelName }} span>span>el-tree>div><divstyle="width: 100%;height: 42%;display: flex;flex-direction: column;position: relative;"><divclass="control toplst"v-if="zheDielist"@click="zheDielist = false"><div>div><div>云台控制div><div><img src="@/assets/carmear/xiala.png" alt="" />div>div><div v-if="zheDielist" style="height: 90%; flex: 1; margin-top: 65px"><div class="control_list"><img@mousedown="cameraBtn(1)"@mouseup="mouseup(1)"class="ShArrows"src="@/assets/jianTou/shang.png"alt=""/><img@mousedown="cameraBtn(2)"@mouseup="mouseup(2)"class="XArrows"src="@/assets/jianTou/xia.png"alt=""/><img@mousedown="cameraBtn(3)"@mouseup="mouseup(3)"class="ZArrows"src="@/assets/jianTou/zuo.png"alt=""/><img@mousedown="cameraBtn(4)"@mouseup="mouseup(4)"class="YArrows"src="@/assets/jianTou/you.png"alt=""/><img@mousedown="cameraBtn(7)"@mouseup="mouseup(7)"class="YSArrows"src="@/assets/jianTou/Yshang.png"alt=""/><img@mousedown="cameraBtn(8)"@mouseup="mouseup(8)"class="YXArrows"src="@/assets/jianTou/Yxia.png"alt=""/><img@mousedown="cameraBtn(6)"@mouseup="mouseup(6)"class="ZXArrows"src="@/assets/jianTou/Zxia.png"alt=""/><img@mousedown="cameraBtn(5)"@mouseup="mouseup(5)"class="ZSArrows"src="@/assets/jianTou/Zshang.png"alt=""/>div><div class="footerLsitStyle_why"><divstyle="padding: 5px"@mousedown="BigCamera(1)"@mouseup="BigCameraMouseup(1)"><img src="@/assets/jianTou/magnify.png" alt="" />div><divstyle="padding: 5px; border-left: 2px solid #1f4075"@mousedown="BigCamera(2)"@mouseup="BigCameraMouseup(2)"><img src="@/assets/jianTou/reduce.png" alt="" />div>div>div><div class="control footer" v-else @click="zheDielist = true"><div>div><div>云台控制div><div><img src="@/assets/carmear/xiala.png" alt="" />div>div>div>div><div style="width: 100%; padding: 10px"><div class="carStyle"><div class="shexinag"><div style="margin-left: 40px; display: flex"><divstyle="padding: 6px; font-size: 17px":class="1 == 1 ? 'tableLIstStyle ' : 'table_hui'">实时监控div><divstyle="padding: 5px; font-size: 17px":class="1 == 2 ? 'tableLIstStyle' : 'table_hui'">录像回放div>div>div>div><ul :class="1 != 1 ? 'FenPingCenter_box' : 'FenPingCenter_list_box'"><li:class="item == FenPingCenType ? 'FenPingCenter_Ui' : 'FenPingCenter_li'"v-for="(item, index) in IconFontNumber":key="item":style="{ width: 100 / IconFontTypenumber + '%' }"><div class="FenPingLise" v-if="item == mouType"><button @click="playerBtnItem(index)">关 闭button>div><divclass="divVide":id="'FenPingCenter_li' + index"@mouseenter="mouseenteBtn(item)"@click="FenPingCenClick({ type: item, Nme: 'FenPingCenter_li' + index })">div>li>ul><div class="footer_box"><div class="iconFlist_box"><span style="color: #fff">分屏 : span><i@mousedown="FenPing(item)"v-for="item in IconFont":key="item.className":class="item.number == IconFontNumber? `   iconFlist  ${item.className}`: ` iconStyle ${item.className}`">i>div><div><ul class="operationUl"><liv-for="(item, index) in operationArray":key="index"@click="FooterBtn(item)"><div><img :src="item.image" alt="" />div><div>{{ item.name }}div>li>ul>div>div>div>div>
template>

定义的变量

data() {return {FenPingCenType: null, // mouType: null,destroyType: null,// 判断是否销毁zheDielist: false, // 左侧云台控制显示uuidv4: '',// uuid 视频放大时使用treeData: [ // 左侧 tree 的数据{id: 1,channelName: "全部",children: [],},],// 图标IconFontNumber: 1,IconFontTypenumber: 1,IconFont: [{className: 'iconfont icontiFenPingOne',number: 1,},{className: 'iconfont icontiFenPingSi',number: 4,},{className: 'iconfont icontiFenPingLiu',number: 6,},],operationArray: [ // 分屏数据// {//   name: '抓拍',//   image: require('../../../assets/carmear/zhuapai.png')// },// {//   name: '放大',//   image: require('../../../assets/carmear/BigList.png')// },// {//   name: '录像',//   image: require('../../../assets/carmear/luxiang.png')// },// {//   name: '音频',//   image: require('../../../assets/carmear/yinpin.png')// },// {//   name: '对讲',//   image: require('../../../assets/carmear/duijiang.png')// },// {//   name: '全屏',//   image: require('../../../assets/carmear/qaunping.png')// },],// tree 重置 数据的属性名defaultProps: {children: 'children',label: 'channelName'},// 部门名称deptName: undefined, // 用于筛选tree 数据selectArry: '',playList: [], // 所有视频的 实例cameraName: null, // 判断是否选中视频checkchannelId: null // 调取视频接口 接收  其他页面传过来的数据};},

css样式


三核心代码的书写

  1. video 划入事件
    // video 划入事件mouseenteBtn(value) {this.mouType = value;console.log(11111)},
  1. video 划出事件
    // video 划入事件mouseout() {setTimeout(() => {this.mouType = null}, 1000)},

提示:视频出来后 显示 全屏或者 抓拍的 按钮 这个块不需要 如果是就一个平并且需要写自己的全屏抓拍样式的话可以用道 这个播放器本身带这些功能 只是样式不好看

     FooterBtn(FooterObj) {console.log(FooterObj.name)if (FooterObj.name == '全屏') {// this.playList[this.FenPingCenType - 1].ShiLi.getFullscreen()} else if (FooterObj.name == '抓拍') {let aasd = ""// 这格式掉后端的接口xxxx({ id: this.defaultPropsBtnBjc.deviceCode }).then(res => {aasd = res.msgwindow.open(aasd).download()})}},
  1. 分屏按钮 分别为 单屏 、四平、六平
  // 分屏按钮FenPing(value) {/*1.当你点击下方的三个图标的时候,分别获取 4 ,3 ,1三个值对应下面的三个判断2. 将对应的盒子添加上是shili:'' ,id(对应的上每一个盒子),当前视频的状态*/this.IconFontNumber = value.numberconsole.log(value.number)if (value.number == 4) {this.IconFontTypenumber = 2for (let index = 1; index < 4; index++) {this.playList.push({ ShiLi: null, id: `${'FenPingCenter_li' + index}`, type: 0, flg: false })}} else {this.IconFontTypenumber = 3for (let index = 1; index < 6; index++) {this.playList.push({ ShiLi: null, id: `${'FenPingCenter_li' + index}`, type: 0, flg: false })}}if (value.number == 1) {this.IconFontTypenumber = 1this.playList = this.playList.splice(0, 1)this.$forceUpdate()}},
  1. 每个分屏 的 实例销毁 按钮
    playerBtnItem(index) {console.log(index); // 这个index是下标/**1.实例销毁调用.ShiLi.destroy();这个方法2.初始化当前的数据的状态*/this.mouType = null;this.destroyType = true;// // 视频的销毁this.playList[index].ShiLi.destroy();this.playList[index].ShiLi = null;this.playList[index].flg = true;this.playList[index].type = 0;},
  1. 联合tree node-click事件
   handleNodeClick(value) {this.defaultPropsBtnBjc = valueconsole.log(value)let a = []/*** 判断是否是tree的最里层的数据*/if (!value.children) {this.playList.forEach(item => {if (item.type == 1) {a.push(item.type)}})// 接口xxxxx({ channelId: value.channelCode || this.checkchannelId }).then(res => {let b = a.length/***   判断是否是 选中 容器*   如果选择容器*   判断他是否为null 查找到他的下标*   拿容器ID 生成 播放器实例*   并且插入到 实例的数据组中*   将播放状态 改为 1* */if (this.cameraName && !this.destroyType) {let player = new Player({id: this.cameraName,isLive: true,plugins: [FlvPlayer],url: res.data.url,autoplay: true,lang: "zh-cn",autoplayMuted: true,"screenShot": true});this.playList[this.FenPingCenType - 1].ShiLi = playerthis.playList[this.FenPingCenType - 1].type = 1} else {/***   判断是否是  是否是 销毁实例后*   判断他是否为null 查找到他的下标*   拿容器ID 生成 播放器实例*   并且插入到 实例的数据组中*   将播放状态 改为1* */if (this.destroyType) {let iB = this.playList.findIndex(item => { return item.ShiLi == null })console.log(iB, 'ppppppp', this.FenPingCenType)if (this.FenPingCenType) {this.playList[this.FenPingCenType - 1].ShiLi = new Player({id: this.cameraName,isLive: true,plugins: [FlvPlayer],url: res.data.url,autoplay: true,lang: "zh-cn",autoplayMuted: true,"screenShot": true});this.playList[this.FenPingCenType - 1].type = 1this.destroyType = !this.playList.every(item => item.type == 1)// this.classLList()} else {this.playList[iB].ShiLi = new Player({id: this.playList[iB].id,isLive: true,plugins: [FlvPlayer],url: res.data.url,autoplay: true,lang: "zh-cn",autoplayMuted: true,"screenShot": true});this.playList[iB].type = 1this.destroyType = !this.playList.every(item => item.type == 1)}} else {for (let i = 0; i < this.playList.length; i++) {if (this.IconFontTypenumber == 1) {this.playList.forEach(item => {if (item.ShiLi != null) {item.ShiLi.destroy();item.ShiLi = null;item.type = 0;let a = new Player({id: this.playList[0].id,isLive: true,plugins: [FlvPlayer],url: res.data.url,autoplay: true,lang: "zh-cn",autoplayMuted: true,"screenShot": true,});item.ShiLi = a}return item})}console.log(9999)if (this.playList[i].ShiLi == null) {this.playList[b].ShiLi = new Player({id: this.playList[b].id,isLive: true,plugins: [FlvPlayer],url: res.data.url,autoplay: true,lang: "zh-cn",autoplayMuted: true,"screenShot": true,playsinline: true,height: window.innerHeight,width: window.innerWidth});this.playList[b].type = 1break;}}}}})}},
  1. 下面的代码是防止报错加的
    // 云台控制必须是球机-上下左右转动cameraBtn(value) {},// 停止事件xx`qmouseup(value) {},// 放大开始事件BigCamera(value) {},// 放大结束事件BigCameraMouseup(value) {}

到此也就结束,使用代码片段的时候需要将图片替换一下不然会出现路径的问题


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部