<template>
|
<div style="width:100%; height: 100%;">
|
<div class="monitoring-right" ref="videoRight">
|
<div class="main-top">
|
<div class="monitoring-video" ref="monitorVideo">
|
<div class="monitoring-video-guid">
|
<span
|
:class="guid === 1 ? 'iconfont icongongge1 activegongge':'iconfont icongongge1'"
|
@click="setGuid(1)"
|
></span>
|
<span
|
:class="guid === 2 ? 'iconfont icongongge activegongge':'iconfont icongongge'"
|
@click="setGuid(2)"
|
></span>
|
<span
|
:class="guid === 3 ? 'iconfont icongongge2 activegongge':'iconfont icongongge2'"
|
@click="setGuid(3)"
|
></span>
|
<el-tooltip v-if="TreeDataPool.selectedNode.id" :content="`${showArea?'隐藏区域':'查看区域'}`" placement="bottom" popper-class="atooltip">
|
<span :class="showArea?'activegongge':''" class="iconfont iconquyu" @click="toggleShowArea"></span>
|
</el-tooltip>
|
<!-- <span
|
v-if="TreeDataPool.selectedNode.id"
|
class="area-trigger"
|
@click="toggleShowArea"
|
>{{showArea?'隐藏区域':'查看区域'}}</span> -->
|
<!-- <el-tooltip
|
v-show="true"
|
:content="`${track ? '关闭追踪': '开启追踪'}`"
|
placement="bottom"
|
popper-class="atooltip"
|
>
|
<span
|
:class="track ? 'iconfont iconintruder-alarm activegongge':'iconfont iconintruder-alarm'"
|
@click="handleTrack"
|
></span>
|
</el-tooltip>-->
|
</div>
|
<div class="fixedRatioBox">
|
<div
|
:class="guid === 1 ? 'video-main-box' : 'video-main-box-side'"
|
v-if="visibilityState"
|
>
|
<video-item
|
v-for="(item, index) in TreeDataPool.videoArr"
|
:key="index"
|
:videoGuid="guid"
|
:videoIndex="index"
|
:videoItem="item"
|
:showArea="showArea"
|
:class="[
|
TreeDataPool.activeVideoIndex === index ? 'activeItem' : '',
|
guid === 1 ? 'onlyActiveItem' : ''
|
]"
|
@click="videoItemClick(index)"
|
></video-item>
|
</div>
|
</div>
|
</div>
|
<div class="monitoring-task" ref="monitorTask">
|
<video-task ref="taskview" @addToBase="toAdd"></video-task>
|
</div>
|
</div>
|
<div class="monitoring-photo">
|
<video-photo ref="photoview" @addToBase="toAdd"></video-photo>
|
</div>
|
</div>
|
|
</div>
|
</template>
|
|
<script>
|
import VideoItem from "../components/VideoItem";
|
import VideoTask from "../components/VideoTask";
|
import VideoPhoto from "../components/VideoPhoto";
|
import { getCameraPlayList } from "@/api/trackCamera";
|
|
export default {
|
name: "Video",
|
components: {
|
VideoItem,
|
VideoTask,
|
VideoPhoto
|
},
|
data () {
|
return {
|
guid: 1,
|
center: "",
|
defaultHeight: 432,
|
defaultWidth: 600,
|
track: false,
|
traceCache: {},
|
traceTimer: null,
|
tracePubUrl: `${location.protocol === "https" ? "wss" : "ws"}://${location.host}/track`,
|
websocket: null,
|
visibilityState: true,
|
showArea: false,
|
};
|
},
|
created () {
|
console.log("befor created")
|
// this.TreeDataPool.clean();
|
// this.TreeDataPool.fetchTreeData();
|
// this.guid = sessionStorage.guid ? Number(sessionStorage.guid) : this.guid;
|
this.TreeDataPool.activeVideoIndex = sessionStorage.activeIndex
|
? Number(sessionStorage.activeIndex)
|
: this.TreeDataPool.activeVideoIndex;
|
this.getActiveIndex();
|
this.TreeDataPool.readonly = true;
|
this.TreeDataPool.gbReadonly = true;
|
this.TreeDataPool.multiple = false;
|
|
console.log("created")
|
},
|
mounted () {
|
document.addEventListener("visibilitychange", this.visibilitychange, false);
|
this.$nextTick(() => {
|
window.addEventListener("resize", this.resizeMonitorTask);
|
//this.getRightWidth();
|
this.resizeMonitorTask();
|
})
|
this.getCenter();
|
this.blackAngWhite();
|
this.VideoPhotoData.queryTagList();
|
|
let list = this.TreeDataPool.localVedioList.filter(i => {
|
return i.progress == 100;
|
})
|
// console.log(list, '已完成的本地视频', this.TreeDataPool.localVedioList)
|
this.TreeDataPool.localVedioList = list;
|
},
|
beforeDestroy () {
|
window.removeEventListener("resize", this.getRightWidth);
|
this.CardList.details = [];
|
window.clearInterval(this.trackTimer);
|
if (this.websocket) {
|
this.websocket.close();
|
}
|
},
|
watch: {
|
"TreeDataPool.videoArr": function (newArry) {
|
console.log('newArry', newArry)
|
const cameras = this.filterNodes(newArry);
|
this.getActiveIndex();
|
this.$refs.taskview.showTasks(cameras);
|
this.$refs.photoview.showCapture(cameras);
|
},
|
"VideoPhotoData.selectBlacks": function (value) {
|
this.blackAngWhite();
|
},
|
"VideoPhotoData.selectWhites": function (value) {
|
this.blackAngWhite();
|
},
|
"TreeDataPool.showTreeBox" (value) {
|
this.getRightWidth();
|
}
|
},
|
methods: {
|
handleTrack () {
|
this.track = !this.track;
|
if (!this.track) {
|
window.clearInterval(this.trackTimer);
|
this.websocket.close();
|
return;
|
}
|
|
this.$notify({
|
type: "success",
|
message: this.track ? "已开启人员追踪" : "已关闭人员追踪"
|
})
|
|
var useWebSocket = true
|
let _this = this
|
|
if (!useWebSocket) {
|
this.trackTimer = window.setInterval(() => {
|
_this.tracking()
|
}, 5 * 1000);
|
} else {
|
this.initTrackWebsocket()
|
this.trackTimer = window.setInterval(() => {
|
_this.videoItemMonitor()
|
}, 1 * 1000);
|
}
|
},
|
videoItemMonitor () {
|
this.websocket.send("ping");
|
|
let cache = this.traceCache
|
// 遍历当期播放的摄像机, 按秒递减摄像机人员存在时间,为0时删除,摄像机人员为空时关闭
|
for (var camera in cache) {
|
// console.log("camera:", camera)
|
// console.table(cache[camera])
|
|
if (Object.keys(cache[camera]).length > 0) {
|
for (var person in cache[camera]) {
|
cache[camera][person]--
|
if (cache[camera][person] < 0) {
|
delete (cache[camera][person])
|
}
|
}
|
|
} else {
|
delete (cache[camera])
|
this.closePlayer(camera)
|
}
|
}
|
},
|
initTrackWebsocket () {
|
if (typeof (WebSocket) === "undefined") {
|
alert("您的浏览器不支持socket")
|
} else {
|
// 实例化socket
|
this.websocket = new WebSocket(this.tracePubUrl)
|
// 监听socket消息
|
this.websocket.onopen = this.websocketonopen
|
this.websocket.onmessage = this.recvieTrackMessage
|
}
|
},
|
websocketonopen () { //连接建立之后执行send方法发送数据
|
this.websocket.send("sub")
|
},
|
tracking () {
|
getCameraPlayList().then(data => {
|
if (data && data.length) {
|
data.forEach(ins => {
|
let newCamera = this.TreeDataPool.getCameraInfoById(ins.NewCameraId)
|
if (!newCamera) {
|
console.log("未查找到摄像机:", ins.NewCameraId);
|
return
|
}
|
if (ins.IsNew) {
|
this.newPlayerInViewBox(newCamera)
|
|
} else {
|
this.replacePlayer(newCamera, ins.OldCameraId)
|
}
|
})
|
}
|
})
|
},
|
recvieTrackMessage (e) {
|
let dataJson = JSON.parse(e.data)
|
let cache = this.traceCache
|
let camera = dataJson.camera
|
let person = dataJson.person
|
let create = false
|
|
// 如果是已经在播放的摄像机, 直接返回
|
if (cache[camera]) {
|
cache[camera][person] = 10
|
return
|
}
|
|
cache[camera] = {}
|
cache[camera][person] = 10
|
|
// 查询播放该人的上一个摄像机
|
for (var cam in cache) {
|
if (cam === camera) {
|
continue
|
}
|
|
if (cache[cam][person]) {
|
// 找到上一个摄像机, 判断摄像机里是否还有其他人, 有:新开播放器 没有:切换
|
console.log("last camera:", cam, Object.keys(cache[cam]).length)
|
if (Object.keys(cache[cam]).length > 2) {
|
delete (cache[cam][person])
|
this.newPlayerInViewBox(camera)
|
return
|
} else {
|
this.replacePlayer(camera, cam)
|
delete (cache[cam])
|
return
|
}
|
}
|
}
|
|
// 未发现播放记录
|
this.newPlayerInViewBox(camera)
|
},
|
newPlayerInViewBox (id) {
|
// 新增播放窗口
|
let camera = this.TreeDataPool.getCameraInfoById(id)
|
let emptyIndex = -1;
|
let exist = false;
|
for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) {
|
// eslint-disable-next-line
|
if (
|
this.TreeDataPool.videoArr[i] === "" ||
|
this.TreeDataPool.videoArr[i] === undefined
|
) {
|
if (emptyIndex === -1) {
|
emptyIndex = i;
|
}
|
} else {
|
if (this.TreeDataPool.videoArr[i].id === camera.id) {
|
exist = true
|
}
|
}
|
}
|
if (!exist && emptyIndex !== -1) {
|
this.TreeDataPool.setVideoArr(emptyIndex, camera, this);
|
}
|
},
|
replacePlayer (id, oldCameraId) {
|
let camera = this.TreeDataPool.getCameraInfoById(id)
|
// console.log("update:", camera.name)
|
// 替换播放器
|
for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) {
|
// eslint-disable-next-line
|
if (
|
this.TreeDataPool.videoArr[i] &&
|
this.TreeDataPool.videoArr[i] !== undefined &&
|
this.TreeDataPool.videoArr[i] !== "") {
|
if (this.TreeDataPool.videoArr[i].id === oldCameraId) {
|
this.TreeDataPool.setVideoArr(i, camera, this);
|
return true
|
}
|
}
|
}
|
|
return false
|
},
|
closePlayer (id) {
|
for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) {
|
// eslint-disable-next-line
|
if (
|
this.TreeDataPool.videoArr[i] &&
|
this.TreeDataPool.videoArr[i] !== undefined &&
|
this.TreeDataPool.videoArr[i] !== "") {
|
if (this.TreeDataPool.videoArr[i].id === id) {
|
this.TreeDataPool.setVideoArr(i, undefined, this);
|
return true
|
}
|
}
|
}
|
},
|
visibilitychange () {
|
switch (document.visibilityState) {
|
case "hidden":
|
this.visibilityState = false;
|
break;
|
case "visible":
|
this.visibilityState = true;
|
break;
|
}
|
},
|
blackAngWhite () {
|
if (this.VideoPhotoData.selectBlacks.length > 0) {
|
for (let i = 0; i < this.VideoPhotoData.whiteList.length; i++) {
|
//this.VideoPhotoData.whiteList[i].disabled = true
|
this.$set(this.VideoPhotoData.whiteList[i], 'disabled', true)
|
}
|
}
|
if (this.VideoPhotoData.selectBlacks.length == 0) {
|
for (let i = 0; i < this.VideoPhotoData.whiteList.length; i++) {
|
//this.VideoPhotoData.whiteList[i].disabled = false
|
this.$set(this.VideoPhotoData.whiteList[i], 'disabled', false)
|
}
|
}
|
if (this.VideoPhotoData.selectWhites.length > 0) {
|
for (let i = 0; i < this.VideoPhotoData.blackList.length; i++) {
|
// this.VideoPhotoData.blackList[i].disabled = true
|
this.$set(this.VideoPhotoData.blackList[i], 'disabled', true)
|
}
|
}
|
if (this.VideoPhotoData.selectWhites.length == 0) {
|
for (let i = 0; i < this.VideoPhotoData.blackList.length; i++) {
|
//this.VideoPhotoData.blackList[i].disabled = false
|
this.$set(this.VideoPhotoData.blackList[i], 'disabled', false)
|
}
|
}
|
},
|
closeWindow (index) {
|
this.CardList.addBaseList.splice(index, 1);
|
},
|
getVideoHeight () {
|
let h = this.$refs.monitorVideo.offsetHeight;
|
this.$refs.monitorTask.style.height = h + 'px';
|
},
|
resizeMonitorTask () {
|
this.getRightWidth();
|
this.getVideoHeight();
|
},
|
getRightWidth () {
|
let w = this.$refs.videoRight.offsetWidth;
|
// console.log("w是:", w,this.$refs.monitorVideo.offsetWidth);
|
this.$refs.monitorTask.style.width = (w - this.$refs.monitorVideo.offsetWidth - 40) + 'px'
|
// console.log("右侧任务的宽度:", this.$refs.monitorTask.style.width)
|
},
|
filterNodes (selectArry) {
|
let nodes = [];
|
selectArry.forEach(i => {
|
if (i && nodes.indexOf(i.id) < 0) {
|
nodes.push(i.id);
|
}
|
});
|
return nodes;
|
},
|
videoItemClick (index) {
|
this.TreeDataPool.activeVideoIndex = index;
|
this.TreeDataPool.activeForceChoose = true;
|
},
|
toAdd (item) {
|
this.CardList.addBaseList.push(item)
|
},
|
getCenter () {
|
this.center = {
|
x: document.documentElement.clientWidth / 2 - 250,
|
y: document.documentElement.clientHeight / 2 - 200
|
};
|
},
|
resizeWidth (w) {
|
this.defaultWidth = w;
|
},
|
resizeHeight (h) {
|
this.defaultHeight = h;
|
},
|
saveAddBase (item, index) {
|
if (this.VideoPhotoData.selectBlacks.length === 0 && this.VideoPhotoData.selectWhites.length === 0) {
|
this.$notify({
|
title: "注意",
|
message: "请选择要添加的底库",
|
type: "warning"
|
})
|
return
|
}
|
let res = this.VideoPhotoData.addBase(item)
|
res.then(data => {
|
console.log("then", data)
|
if (data.success) {
|
this.$notify({
|
title: "成功",
|
message: data.data,
|
type: "success"
|
})
|
} else {
|
this.$notify({
|
title: "失败",
|
message: data.data,
|
type: "error"
|
})
|
}
|
this.CardList.addBaseList.splice(index, 1);
|
this.VideoPhotoData.selectBlacks = []
|
this.VideoPhotoData.selectWhites = []
|
})
|
},
|
getActiveIndex () {
|
this.TreeDataPool.videoArr.length = Math.pow(this.guid, 2);
|
let nullVideoIndex = "";
|
for (let i = 0; i < this.TreeDataPool.videoArr.length; i++) {
|
// eslint-disable-next-line
|
if (
|
this.TreeDataPool.videoArr[i] === "" ||
|
this.TreeDataPool.videoArr[i] === undefined
|
) {
|
nullVideoIndex = i;
|
} else {
|
nullVideoIndex = "";
|
}
|
}
|
if (
|
this.TreeDataPool.activeVideoIndex !== "" &&
|
this.TreeDataPool.activeVideoIndex <
|
this.TreeDataPool.videoArr.length - 1
|
) {
|
return this.TreeDataPool.activeVideoIndex;
|
} else {
|
if (nullVideoIndex === "") {
|
this.TreeDataPool.activeVideoIndex =
|
this.TreeDataPool.videoArr.length - 1;
|
} else {
|
this.TreeDataPool.activeVideoIndex = nullVideoIndex;
|
}
|
}
|
},
|
setGuid (value) {
|
clearTimeout(this.trackTimer);
|
|
if (value < this.guid && this.TreeDataPool.activeVideoIndex > value) {
|
// eslint-disable-next-line
|
for (
|
let i = this.TreeDataPool.activeVideoIndex - 1;
|
i < this.TreeDataPool.videoArr.length;
|
i++
|
) {
|
// eslint-disable-next-line
|
if (
|
this.TreeDataPool.videoArr[i] &&
|
this.TreeDataPool.videoArr[i]["isPlaying"]
|
) {
|
this.TreeDataPool.videoArr[i]["isPlaying"] = false;
|
}
|
}
|
}
|
this.guid = value;
|
sessionStorage.guid = this.guid;
|
sessionStorage.activeIndex = this.TreeDataPool.activeVideoIndex;
|
this.getActiveIndex();
|
},
|
toggleShowArea () {
|
this.showArea = !this.showArea;
|
}
|
},
|
destroyed () {
|
window.removeEventListener("resize", this.getRightWidth);
|
this.CardList.details = [];
|
this.CardList.addBaseList = [];
|
this.VideoPhotoData.selectBlacks = [];
|
this.VideoPhotoData.selectWhites = [];
|
//this.TreeDataPool.treeActiveName = "camera";
|
}
|
};
|
</script>
|
|
<style lang="scss">
|
.monitoring-right {
|
width: 100%;
|
height: 100%;
|
min-width: 981px;
|
//float: right;
|
box-sizing: border-box;
|
padding: 10px;
|
background-color: #e9ebf2;
|
.main-top {
|
margin-bottom: 14px;
|
display: flex;
|
justify-content: space-between;
|
}
|
.monitoring-video {
|
width: 70.5%;
|
min-width: 740px;
|
max-width: 1208px;
|
height: 98%;
|
//float: left;
|
box-sizing: border-box;
|
// box-shadow: #e4e7ed 0px 0px 9px inset;
|
border-radius: 5px;
|
.activeItem {
|
border: 3px solid #ff7733;
|
position: relative;
|
top: -1px;
|
left: -1px;
|
// width: calc(100% + 2px) !important;
|
// height: calc(100% + 2px) !important;
|
}
|
.onlyActiveItem {
|
width: calc(100% + 2px) !important;
|
height: calc(100% + 2px) !important;
|
}
|
.video-main-box {
|
background-color: #fff;
|
box-sizing: border-box;
|
border: 1px solid #cacaca;
|
}
|
.video-main-box-side {
|
border-top: 1px solid #cacaca;
|
border-left: 1px solid #cacaca;
|
box-sizing: border-box;
|
background-color: #fff;
|
}
|
.monitoring-video-guid {
|
text-align: right;
|
padding-bottom: 10px;
|
.activegongge {
|
color: #3d68e1;
|
}
|
span {
|
font-size: 20px;
|
color: #cacaca;
|
padding-left: 12px;
|
cursor: pointer;
|
}
|
.area-trigger {
|
font-size: 16px;
|
}
|
}
|
.fixedRatioBox {
|
padding-top: 56.3%;
|
box-sizing: border-box;
|
position: relative;
|
> div {
|
width: 100%;
|
height: 100%;
|
position: absolute;
|
top: 0;
|
}
|
}
|
}
|
.monitoring-task {
|
//width: calc(29.5% - 10px);
|
width: calc(34% - 10px);
|
//width: auto;
|
background-color: #fff;
|
float: left;
|
margin: 0px 0px 0px 10px;
|
box-sizing: border-box;
|
border: 1px solid #e4e7ed;
|
// box-shadow: #e4e7ed 0px 0px 9px inset;
|
border-radius: 5px;
|
min-width: 200px;
|
}
|
|
.monitoring-photo {
|
width: 100%;
|
height: calc(25% + 32px);
|
background-color: #fff;
|
float: left;
|
padding: 10px;
|
//margin-top: -10px;
|
box-sizing: border-box;
|
border: 1px solid #e4e7ed;
|
// box-shadow: #e4e7ed 0px 0px 9px inset;
|
border-radius: 5px;
|
}
|
}
|
.titlebar {
|
height: 10px !important;
|
background: #fff !important;
|
.button {
|
position: absolute;
|
font-size: 25px !important;
|
right: 10px;
|
top: 10px;
|
z-index: 3;
|
}
|
}
|
.addToBase {
|
width: 98%;
|
height: 430px;
|
position: relative;
|
.topLabel {
|
margin-top: 20px;
|
height: 40px;
|
border-bottom: 1px solid #eee;
|
font-family: PingFangSC-Medium;
|
font-size: 20px;
|
font-weight: 600;
|
line-height: 1rem;
|
color: #222222;
|
text-align: left;
|
margin-left: 15px;
|
}
|
.items {
|
width: 100%;
|
height: auto;
|
max-height: 35%;
|
overflow-y: auto;
|
margin: 20px 0px;
|
.lable {
|
width: 15%;
|
margin-top: 10px;
|
float: left;
|
//font-family: PingFangSC-Medium;
|
font-size: 14px;
|
font-weight: 600;
|
}
|
.baseList {
|
width: 85%;
|
height: 100%;
|
float: left;
|
|
// display: flex;
|
// justify-content: flex-start;
|
.base {
|
//flex-wrap: wrap;
|
width: calc(33% - 10px);
|
padding: 0px 5px;
|
line-height: 30px;
|
float: left;
|
text-align: left;
|
font-size: 12px !important;
|
.el-checkbox {
|
width: 100%;
|
display: block;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
.el-checkbox__label {
|
display: inline !important;
|
}
|
}
|
}
|
}
|
}
|
.buttons {
|
position: absolute;
|
right: 0px;
|
bottom: 15px;
|
}
|
}
|
</style>
|