<template>
|
<div style="width:100%; height: 100%;">
|
<div class="monitoring-right" ref="videoRight">
|
<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-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="guid === 1 ? 'video-main-box' : 'video-main-box-side'"
|
style="width: 100%; height: calc(100% - 52px);"
|
v-if="visibilityState"
|
>
|
<video-item
|
v-for="(item, index) in TreeDataPool.videoArr"
|
:key="index"
|
:videoGuid="guid"
|
:videoIndex="index"
|
:videoItem="item"
|
:class="[
|
TreeDataPool.activeVideoIndex === index ? 'activeItem' : '',
|
guid === 1 ? 'onlyActiveItem' : ''
|
]"
|
@click="videoItemClick(index)"
|
></video-item>
|
</div>
|
</div>
|
<div class="monitoring-task" ref="monitorTask">
|
<video-task ref="taskview" @addToBase="toAdd"></video-task>
|
</div>
|
<div class="monitoring-photo">
|
<video-photo ref="photoview" @addToBase="toAdd"></video-photo>
|
</div>
|
</div>
|
<hsc-window-style-metal class="windown-model">
|
<hsc-window
|
v-for="(item, index) in CardList.addBaseList"
|
:closeButton="true"
|
@closebuttonclick="closeWindow(index)"
|
:key="index"
|
@update:height="resizeHeight"
|
@update:width="resizeWidth"
|
style="background:white; height:475px"
|
:left="center.x + index * 10"
|
:top="center.y + index * 10"
|
:resizable="true"
|
positionHint="center"
|
:isScrollable="true"
|
:minWidth="662"
|
:minHeight="479"
|
:maxWidth="10000"
|
:maxHeight="7000"
|
:height="defaultHeight"
|
:width="defaultWidth"
|
>
|
<div class="addToBase">
|
<div class="topLabel">加入底库</div>
|
<div class="items">
|
<div class="lable">
|
<p>黑名单 ></p>
|
</div>
|
<div class="baseList">
|
<el-checkbox-group v-model="VideoPhotoData.selectBlacks" @change="blackAngWhite">
|
<div class="base" v-for="(item, index) in VideoPhotoData.blackList" :key="index">
|
<el-checkbox
|
:label="item.value"
|
:title="item.title"
|
:disabled="item.disabled"
|
>{{item.title}}</el-checkbox>
|
</div>
|
</el-checkbox-group>
|
</div>
|
</div>
|
<div class="items">
|
<div class="lable">
|
<p>白名单 ></p>
|
</div>
|
<div class="baseList">
|
<el-checkbox-group v-model="VideoPhotoData.selectWhites" @change="blackAngWhite">
|
<div class="base" v-for="(item, index) in VideoPhotoData.whiteList" :key="index">
|
<el-checkbox
|
:label="item.value"
|
:title="item.title"
|
:disabled="item.disabled"
|
>{{item.title}}</el-checkbox>
|
</div>
|
</el-checkbox-group>
|
</div>
|
</div>
|
<div class="buttons">
|
<el-button type="primary" @click="saveAddBase(item, index)">保存</el-button>
|
<el-button type="default" @click="closeWindow(index)">取消</el-button>
|
</div>
|
</div>
|
</hsc-window>
|
</hsc-window-style-metal>
|
</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
|
};
|
},
|
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.getRightWidth);
|
this.getRightWidth();
|
})
|
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);
|
},
|
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();
|
}
|
},
|
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%;
|
float: right;
|
box-sizing: border-box;
|
padding: 10px;
|
background-color: #e9ebf2;
|
.monitoring-video {
|
width: 70.5%;
|
min-width: 740px;
|
max-width: 1208px;
|
height: 75%;
|
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;
|
}
|
}
|
}
|
.monitoring-task {
|
// @media screen and (max-width: 1700px){
|
|
// }
|
width: calc(29.5% - 10px);
|
//width: auto;
|
// width: 23%;
|
height: 73%;
|
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% + 10px);
|
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;
|
}
|
}
|
</style>
|