Browse Source

perf 更换为多视频监控

master
zhangqi 2 years ago
parent
commit
f69ba53cca
  1. BIN
      dist.rar
  2. 5
      src/api/urls.js
  3. 22
      src/components/Map/ToiletMap.vue
  4. 2
      src/components/Map/components/Map.vue
  5. 81
      src/components/Map/components/Monitor.vue
  6. 153
      src/components/Map/components/Monitor0.vue
  7. 252
      src/components/Map/components/Monitor1.vue
  8. 18
      src/components/Map/components/ToiletDetail.vue
  9. 3
      src/views/Cockpit/Cockpit.vue

BIN
dist.rar

5
src/api/urls.js

@ -35,12 +35,13 @@ export const transformMapApi = 'shaoxing-plat/v1/transform-picture/list'
export const getM3u8Api = 'shaoxing-plat/v1/video/start' export const getM3u8Api = 'shaoxing-plat/v1/video/start'
// 获取监控-imou // 获取监控-imou
// export const getImouApi = 'shaoxing-plat/v1/video/imou' // export const getImouApi = 'shaoxing-plat/v1/video/imou'
export const getVideoList = 'shaoxing-plat/v1/picture/video-list'
// 获取监控-imou // 获取监控-imou
export const getImouApi = 'shaoxing-plat/v1/video/imou-live' export const getImouApi = 'shaoxing-plat/v1/video/imou-live'
export const getNewImouApi = 'shaoxing-plat/v1/video/imou-live-new'
// 获取监控回放-imou // 获取监控回放-imou
export const getImouReturnApi = 'shaoxing-plat/v1/video/imou-return' export const getImouReturnApi = 'shaoxing-plat/v1/video/imou-return'
export const getNewImouReturnApi = 'shaoxing-plat/v1/video/imou-return-new'
/* 公厕信息管理接口 **/ /* 公厕信息管理接口 **/
// 获取厕所列表 get // 获取厕所列表 get
export const toiletListApi = 'shaoxing-plat/v1/toilet/page' export const toiletListApi = 'shaoxing-plat/v1/toilet/page'

22
src/components/Map/ToiletMap.vue

@ -66,7 +66,7 @@
import { coiletConfig, videoConfig } from './config/marker-config' import { coiletConfig, videoConfig } from './config/marker-config'
import { toiletGrade } from './config/toiletmap' import { toiletGrade } from './config/toiletmap'
import request from '@/api/request' import request from '@/api/request'
import { toiletMapApi, videoMapApi, toiletDetailApi } from '@/api/urls'
import { toiletMapApi, videoMapApi, toiletDetailApi, getVideoList } from '@/api/urls'
import ToiletDetail from './components/ToiletDetail' import ToiletDetail from './components/ToiletDetail'
import Monitor from './components/Monitor' import Monitor from './components/Monitor'
import Map from './components/Map' import Map from './components/Map'
@ -202,9 +202,10 @@ export default {
'</div>'; '</div>';
el.onclick = function (e) { el.onclick = function (e) {
if (e.target.nodeName === 'A') { if (e.target.nodeName === 'A') {
_that.showMonitor(res.data.id, res.data.toiletName)
_that.getVideoLists(res.data.id, res.data.toiletName)
} }
} }
console.log(this.$refs.mapContainer)
// this.$refs.mapContainer.showInfo(el, info, true, 'top-left', 0, -20) // this.$refs.mapContainer.showInfo(el, info, true, 'top-left', 0, -20)
this.$refs.mapContainer.showInfoWin(tdtMap, el, lnglat, 0, -30) this.$refs.mapContainer.showInfoWin(tdtMap, el, lnglat, 0, -30)
} }
@ -294,9 +295,22 @@ export default {
this.filter.regionParamVOList = this.$store.state.nomalMapArea this.filter.regionParamVOList = this.$store.state.nomalMapArea
this.bounds = this.$store.state.nomalMapBounds this.bounds = this.$store.state.nomalMapBounds
}, },
showMonitor (id, title) {
async getVideoLists (id, title) {
var res = await request.get(getVideoList, {
params: {
toiletId: id
}
})
if (res.code === '200') {
this.$refs.monitor.viewMonitor(res.data, title)
// this.$emit('showMonitor', res.data, this.title)
} else {
this.$message.info(res.message)
}
},
showMonitor (data, title) {
// this.$message.info('线') // this.$message.info('线')
this.$refs.monitor.viewMonitor(id, title)
this.$refs.monitor.viewMonitor(data, title)
}, },
// initTdt() { // initTdt() {
// this.tdtMap = new T.Map('map-wrapper') // this.tdtMap = new T.Map('map-wrapper')

2
src/components/Map/components/Map.vue

@ -81,6 +81,7 @@ export default {
}, },
onMouseover: function() { onMouseover: function() {
const { markerInfo, thisMarker } = this const { markerInfo, thisMarker } = this
console.log(thisMarker)
_that.$emit('markerHandelMouseover', markerInfo, thisMarker, _that.tdtMap) _that.$emit('markerHandelMouseover', markerInfo, thisMarker, _that.tdtMap)
}, },
onMouseout: function() { onMouseout: function() {
@ -100,6 +101,7 @@ export default {
this.infoWindow.open(this.map, new AMap.LngLat(info.yCoordinates, info.xCoordinates)) this.infoWindow.open(this.map, new AMap.LngLat(info.yCoordinates, info.xCoordinates))
}, },
showInfoWin(tdtMap, name, p, x, y) { showInfoWin(tdtMap, name, p, x, y) {
console.log(tdtMap)
this.infoWindow = new T.InfoWindow(name, { this.infoWindow = new T.InfoWindow(name, {
offset: new T.Point(x, y), offset: new T.Point(x, y),
closeOnClick: true, closeOnClick: true,

81
src/components/Map/components/Monitor.vue

@ -27,6 +27,9 @@
<a class="bt_submit" @click="returnVideo">回放</a> <a class="bt_submit" @click="returnVideo">回放</a>
<a class="bt_submit" @click="resetPlay">监控</a> <a class="bt_submit" @click="resetPlay">监控</a>
</div> </div>
<div class="check-box">
<el-button type="primary" :plain="currVideo === i ? false : true" size="mini" v-for="(item, i) in videoList" :key="i" @click="changeVideo(i)">{{`监控视频${i + 1}`}}</el-button>
</div>
<div id="monitor"> <div id="monitor">
<video ref="video" controls v-if="type === 2"></video> <video ref="video" controls v-if="type === 2"></video>
</div> </div>
@ -43,13 +46,15 @@
<script> <script>
import request from '@/api/request' import request from '@/api/request'
import { getImouApi, getImouReturnApi } from '@/api/urls'
import { getImouApi, getNewImouApi, getImouReturnApi, getNewImouReturnApi } from '@/api/urls'
export default { export default {
data () { data () {
return { return {
title: '', title: '',
id: '', id: '',
videoList: [],
showMonitor: false, showMonitor: false,
currVideo: 0,
type: 1, type: 1,
m3u8Url: '', m3u8Url: '',
imouUrl: '', imouUrl: '',
@ -65,19 +70,36 @@ export default {
} }
}, },
methods: { methods: {
async viewMonitor (id, title) {
this.id = id
async viewMonitor (list, title) {
this.videoList = list
console.log(list)
this.title = title + '视频' this.title = title + '视频'
this.showMonitor = true this.showMonitor = true
this.autoCloseChange() this.autoCloseChange()
// this.playMonitorToM3u8() // this.playMonitorToM3u8()
this.getUrl()
this.getUrl(list)
// console.log(res) // console.log(res)
}, },
async getUrl () {
var res = await request.get(getImouApi, {
// async getUrl () {
// var res = await request.get(getImouApi, {
// params: {
// toiletId: this.id
// }
// })
// if (res.code === '200') {
// // this.m3u8Url = res.data.videoUrl
// // this.playMonitorToM3u8()
// this.imouUrl = res.data.url
// this.kitToken = res.data.kitToken
// this.playMonitorToImou(res.data.url, res.data.kitToken)
// } else {
// this.$message.info(res.message)
// }
// },
async getUrl(list) {
var res = await request.get(getNewImouApi, {
params: { params: {
toiletId: this.id
videoConfigId: list[this.currVideo].id
} }
}) })
if (res.code === '200') { if (res.code === '200') {
@ -90,6 +112,13 @@ export default {
this.$message.info(res.message) this.$message.info(res.message)
} }
}, },
changeVideo(i) {
if (i !== this.currVideo) {
this.currVideo = i
this.handleClose(false)
this.getUrl(this.videoList)
}
},
playMonitorToM3u8 () { playMonitorToM3u8 () {
if (Hls.isSupported()) { if (Hls.isSupported()) {
this.Hls = new Hls(); this.Hls = new Hls();
@ -154,6 +183,31 @@ export default {
this.endTime = '' this.endTime = ''
} }
}, },
// async returnVideo () {
// if (!this.date) {
// this.$message.info('')
// return
// }
// if (!this.timeSection) {
// this.$message.info('')
// return
// }
// var res = await request.get(getImouReturnApi, {
// params: {
// toiletId: this.id,
// startTime: this.startTime,
// endTime: this.endTime
// }
// })
// if (res.code === '200') {
// this.player && this.player.destroy()
// this.player = null
// this.playMonitorToImou(res.data.url, res.data.kitToken)
// } else {
// this.$message.info(res.message)
// }
// console.log(res)
// },
async returnVideo () { async returnVideo () {
if (!this.date) { if (!this.date) {
this.$message.info('请选择日期') this.$message.info('请选择日期')
@ -163,9 +217,9 @@ export default {
this.$message.info('请选择时间段') this.$message.info('请选择时间段')
return return
} }
var res = await request.get(getImouReturnApi, {
var res = await request.get(getNewImouReturnApi, {
params: { params: {
toiletId: this.id,
videoConfigId: this.videoList[this.currVideo].id,
startTime: this.startTime, startTime: this.startTime,
endTime: this.endTime endTime: this.endTime
} }
@ -184,7 +238,7 @@ export default {
this.player = null this.player = null
this.playMonitorToImou(this.imouUrl, this.kitToken) this.playMonitorToImou(this.imouUrl, this.kitToken)
}, },
handleClose () {
handleClose (close = true) {
clearTimeout(this.timer) clearTimeout(this.timer)
if (this.type === 1 && this.player) { if (this.type === 1 && this.player) {
this.player.stop() this.player.stop()
@ -198,7 +252,11 @@ export default {
this.$refs.video.removeAttribute('src') this.$refs.video.removeAttribute('src')
this.$refs.video.load() this.$refs.video.load()
} }
if (close) {
this.showMonitor = false this.showMonitor = false
this.currVideo = 0
}
} }
} }
} }
@ -231,6 +289,9 @@ export default {
margin-right: 0 !important; margin-right: 0 !important;
} }
} }
.check-box {
padding: 10px 10px 5px 10px;
}
#monitor { #monitor {
width: 800px; width: 800px;
height: 450px; height: 450px;

153
src/components/Map/components/Monitor0.vue

@ -1,153 +0,0 @@
<template>
<el-dialog
:title="title"
:visible.sync="showMonitor"
:before-close="handleClose"
:modal-append-to-body="false">
<div class="detail-content">
<div id="monitor">
<div class="tool">
<el-date-picker
v-model="dateSection"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy/M/d HH:mm:ss"
@change="handleChange">
</el-date-picker>
</div>
<video ref="video" controls v-if="type === 2"></video>
</div>
</div>
</el-dialog>
</template>
<script>
import request from '@/api/request'
import { getM3u8Api, getImouApi } from '@/api/urls'
export default {
data () {
return {
title: '',
showMonitor: false,
type: 2,
m3u8Url: '',
imouUrl: '',
player: null,
Hls: null,
dateSection: [],
startTime: '',
endTime: ''
}
},
methods: {
async viewMonitor (id, title) {
this.title = title + '视频'
this.showMonitor = true
// this.playMonitorToM3u8()
var res = await request.get(getM3u8Api, {
params: {
toiletId: 2
}
})
if (res.code === '200') {
this.m3u8Url = res.data.hls
this.playMonitorToM3u8()
// this.playMonitorToImou(res.data.url, res.data.kitToken)
} else {
this.$message.info(res.message)
}
// console.log(res)
},
playMonitorToM3u8 () {
if (Hls.isSupported()) {
if (this.Hls) this.Hls.destroy()
this.Hls = new Hls();
// this.Hls.loadSource('http://cmgw-vpc.lechange.com:8888/LCO/5L060F4PAAD53DB/0/1/20210719T080253/f741fbd46fe34fe3cd794c4931a05c8e.m3u8');
this.Hls.loadSource(this.m3u8Url);//
this.Hls.attachMedia(this.$refs.video); //video
this.Hls.on(Hls.Events.MANIFEST_PARSED, () => {
this.$refs.video.play();
console.log("加载成功");
});
this.Hls.on(Hls.Events.ERROR, (event, data) => {
//
console.log("加载失败");
})
} else {
this.$message.error("不支持的格式");
return;
}
},
playMonitorToImou (url, token) {
if (!this.player) this.player = new ImouPlayer('#monitor')
this.player.setup({
src: [
{
url: url,
kitToken: token
}
],
width: 800,
height: 450,
poster: '',
autoplay: true,
controls: true,
})
this.player.play()
},
handleChange (val) {
if (val) {
this.startTime = val[0]
this.endTime = val[1]
} else {
this.loginStartTime = ''
this.loginEndTime = ''
}
},
handleClose () {
if (this.type === 1 && this.player) {
this.player.stop()
this.player.destroy()
}
if (this.type === 2 && this.Hls) {
this.Hls.destroy()
this.Hls = null
this.$refs.video.pause()
this.$refs.video.removeAttribute('src')
this.$refs.video.load()
}
this.showMonitor = false
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-dialog {
width: 800px;
border-radius: 8px;
overflow: hidden;
.detail-content {
#monitor {
width: 800px;
// height: 450px;
.tool {
padding: 10px;
.el-date-editor {
.el-range__icon {
height: 14px;
line-height: 100%;
}
}
}
video {
width: 100%;
height: 450px;
}
}
}
}
</style>

252
src/components/Map/components/Monitor1.vue

@ -0,0 +1,252 @@
<template>
<el-dialog
:title="title"
:visible.sync="showMonitor"
:before-close="handleClose"
:modal-append-to-body="false">
<div class="detail-content">
<div class="tool">
<span class="label">回放</span>
<el-date-picker
v-model="date"
type="date"
value-format="yyyy/M/d"
placeholder="选择日期"
@change="handleChangeDate">
</el-date-picker>
<el-time-picker
is-range
v-model="timeSection"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
value-format="HH:mm:ss"
@change="handleChangeTime">
</el-time-picker>
<a class="bt_submit" @click="returnVideo">回放</a>
<a class="bt_submit" @click="resetPlay">监控</a>
</div>
<div id="monitor">
<video ref="video" controls v-if="type === 2"></video>
</div>
<div class="auto-box">
<el-switch
v-model="autoClose"
@change="autoCloseChange">
</el-switch>
<span class="text">十分钟后自动关闭</span>
</div>
</div>
</el-dialog>
</template>
<script>
import request from '@/api/request'
import { getImouApi, getImouReturnApi } from '@/api/urls'
export default {
data () {
return {
title: '',
id: '',
showMonitor: false,
type: 1,
m3u8Url: '',
imouUrl: '',
kitToken: '',
player: null,
Hls: null,
autoClose: true,
timer: null,
date: '',
timeSection: ['00:00:00', '23:59:59'],
startTime: '',
endTime: ''
}
},
methods: {
async viewMonitor (id, title) {
this.id = id
this.title = title + '视频'
this.showMonitor = true
this.autoCloseChange()
// this.playMonitorToM3u8()
this.getUrl()
// console.log(res)
},
async getUrl () {
var res = await request.get(getImouApi, {
params: {
toiletId: this.id
}
})
if (res.code === '200') {
// this.m3u8Url = res.data.videoUrl
// this.playMonitorToM3u8()
this.imouUrl = res.data.url
this.kitToken = res.data.kitToken
this.playMonitorToImou(res.data.url, res.data.kitToken)
} else {
this.$message.info(res.message)
}
},
playMonitorToM3u8 () {
if (Hls.isSupported()) {
this.Hls = new Hls();
// this.Hls.loadSource('http://cmgw-vpc.lechange.com:8888/LCO/5L060F4PAAD53DB/0/1/20210719T080253/f741fbd46fe34fe3cd794c4931a05c8e.m3u8');
this.Hls.loadSource(this.m3u8Url);//
this.Hls.attachMedia(this.$refs.video); //video
this.Hls.on(Hls.Events.MANIFEST_PARSED, () => {
this.$refs.video.play();
console.log("加载成功");
});
this.Hls.on(Hls.Events.ERROR, (event, data) => {
//
console.log("加载失败");
})
} else {
this.$message.error("不支持的格式");
return;
}
},
playMonitorToImou (url, token) {
if (!this.player) this.player = new ImouPlayer('#monitor')
this.player.setup({
src: [
{
url: url,
kitToken: token
}
],
width: 800,
height: 450,
poster: '',
autoplay: true,
controls: true,
})
this.player.play()
},
autoCloseChange () {
var _that = this
if (this.autoClose) {
this.timer = setTimeout(() => {
_that.handleClose()
}, 1000 * 60 * 10);
} else {
clearTimeout(this.timer)
}
},
handleChangeDate (val) {
if (val && this.timeSection) {
this.startTime = val + ' ' + this.timeSection[0]
this.endTime = val + ' ' + this.timeSection[1]
} else {
this.startTime = ''
this.endTime = ''
}
},
handleChangeTime (val) {
if (val) {
this.startTime = this.date + ' ' + val[0]
this.endTime = this.date + ' ' + val[1]
} else {
this.startTime = ''
this.endTime = ''
}
},
async returnVideo () {
if (!this.date) {
this.$message.info('请选择日期')
return
}
if (!this.timeSection) {
this.$message.info('请选择时间段')
return
}
var res = await request.get(getImouReturnApi, {
params: {
toiletId: this.id,
startTime: this.startTime,
endTime: this.endTime
}
})
if (res.code === '200') {
this.player && this.player.destroy()
this.player = null
this.playMonitorToImou(res.data.url, res.data.kitToken)
} else {
this.$message.info(res.message)
}
console.log(res)
},
resetPlay () {
this.player && this.player.destroy()
this.player = null
this.playMonitorToImou(this.imouUrl, this.kitToken)
},
handleClose () {
clearTimeout(this.timer)
if (this.type === 1 && this.player) {
this.player.stop()
this.player.destroy()
this.player = null
}
if (this.type === 2 && this.Hls) {
this.Hls && this.Hls.destroy()
this.Hls = null
this.$refs.video.pause()
this.$refs.video.removeAttribute('src')
this.$refs.video.load()
}
this.showMonitor = false
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-dialog {
width: 800px;
border-radius: 8px;
overflow: hidden;
.detail-content {
.tool {
padding: 10px;
display: flex;
.label {
line-height: 30px;
}
.el-date-editor {
.el-range__icon {
height: 14px;
line-height: 100%;
}
.el-icon-date {
height: 14px;
line-height: 30px;
}
}
a {
margin-left: 10px;
margin-right: 0 !important;
}
}
#monitor {
width: 800px;
height: 450px;
video {
width: 100%;
height: 100%;
}
}
.auto-box {
padding: 10px;
@include lineHeight(40px);
.text {
margin-left: 10px;
font-size: 12px;
}
}
}
}
</style>

18
src/components/Map/components/ToiletDetail.vue

@ -133,7 +133,7 @@
<script> <script>
import { toiletGrade, yesno } from '../config/toiletmap' import { toiletGrade, yesno } from '../config/toiletmap'
import request from '@/api/request' import request from '@/api/request'
import { toiletDetailApi, realTimeApi, lineChartApi } from '@/api/urls'
import { toiletDetailApi, realTimeApi, lineChartApi, getVideoList } from '@/api/urls'
export default { export default {
data () { data () {
return { return {
@ -248,8 +248,20 @@ export default {
}) })
this.deviceArr = left.concat(right) this.deviceArr = left.concat(right)
}, },
showMonitor () {
this.$emit('showMonitor', this.id, this.title)
// showMonitor () {
// this.$emit('showMonitor', this.id, this.title)
// }
async showMonitor () {
var res = await request.get(getVideoList, {
params: {
toiletId: this.id
}
})
if (res.code === '200') {
this.$emit('showMonitor', res.data, this.title)
} else {
this.$message.info(res.message)
}
} }
} }
} }

3
src/views/Cockpit/Cockpit.vue

@ -876,7 +876,10 @@ export default {
initTdt() { initTdt() {
this.tdtMap = new T.Map('map-wrapper') this.tdtMap = new T.Map('map-wrapper')
this.tdtMap.centerAndZoom(new T.LngLat(120.65735, 29.85791), 10) this.tdtMap.centerAndZoom(new T.LngLat(120.65735, 29.85791), 10)
console.log(this.tdtMap)
if (this.tdtMap.setStyle) {
this.tdtMap.setStyle('indigo') this.tdtMap.setStyle('indigo')
}
this.getList(1) this.getList(1)
} }
}, },

Loading…
Cancel
Save