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样式
三核心代码的书写
- video 划入事件
// video 划入事件mouseenteBtn(value) {this.mouType = value;console.log(11111)},
- 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()})}},
- 分屏按钮 分别为 单屏 、四平、六平
// 分屏按钮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()}},
- 每个分屏 的 实例销毁 按钮
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;},
- 联合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;}}}}})}},
- 下面的代码是防止报错加的
// 云台控制必须是球机-上下左右转动cameraBtn(value) {},// 停止事件xx`qmouseup(value) {},// 放大开始事件BigCamera(value) {},// 放大结束事件BigCameraMouseup(value) {}
到此也就结束,使用代码片段的时候需要将图片替换一下不然会出现路径的问题
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
