优化首页大屏监控加载问题

main
junhong 2 days ago
parent 3aa439dc0d
commit 0e193fd93e
  1. 49
      public/dahua/demo.html
  2. 145
      src/views/large-screen/index.vue
  3. 23
      src/views/large-screen/video.vue
  4. 4
      src/views/login.vue

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -16,13 +17,15 @@
flex-wrap: wrap; flex-wrap: wrap;
padding: 20px; padding: 20px;
} }
.container { .container {
display: flex; display: flex;
padding: 0 0px !important; padding: 0 0px !important;
margin: 0!important; margin: 0 !important;
max-width: none; max-width: none;
height: 100vh; height: 100vh;
} }
.real-container, .real-container,
.record-container { .record-container {
width: 45%; width: 45%;
@ -30,18 +33,22 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.has-success .valid-feedback{
.has-success .valid-feedback {
display: unset; display: unset;
} }
.cursor-pointer { .cursor-pointer {
cursor: pointer; cursor: pointer;
} }
.list-group a { .list-group a {
text-decoration: none; text-decoration: none;
color: #13425c; color: #13425c;
} }
</style> </style>
</head> </head>
<body> <body>
<div class="alert alert-dismissible alert-primary" style="display: none;"> <div class="alert alert-dismissible alert-primary" style="display: none;">
<button type="button" class="btn-close" data-bs-dismiss="alert"></button> <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
@ -50,7 +57,8 @@
<!-- 右侧固定小弹窗 --> <!-- 右侧固定小弹窗 -->
<div style="position: fixed; right: 0; top: 60px; width: 250px;display: none;"> <div style="position: fixed; right: 0; top: 60px; width: 250px;display: none;">
<p style="font-size: 20px;"> <p style="font-size: 20px;">
<button type="button" class="btn btn-outline-secondary"><a href="/demo_api.html">点击跳转到功能api-demo页面</a></button> <button type="button" class="btn btn-outline-secondary"><a
href="/demo_api.html">点击跳转到功能api-demo页面</a></button>
</p> </p>
<div class="platform-info"> <div class="platform-info">
大华平台信息 大华平台信息
@ -93,7 +101,8 @@
<div id="ws-record-player" style="height: 500px; margin-bottom: 20px;"></div> <div id="ws-record-player" style="height: 500px; margin-bottom: 20px;"></div>
<div style="display: flex;"> <div style="display: flex;">
<!-- 日期 --> <!-- 日期 -->
<input style="width:140px;" type="date" id="date" class="form-control" id="record-date" value="2024-09-17"/> <input style="width:140px;" type="date" id="date" class="form-control" id="record-date"
value="2024-09-17" />
<button style="margin:0 5px" type="button" class="btn btn-outline-primary" id="record-btn">录像回放</button> <button style="margin:0 5px" type="button" class="btn btn-outline-primary" id="record-btn">录像回放</button>
<button type="button" class="btn btn-outline-primary" id="close-record">关闭录像</button> <button type="button" class="btn btn-outline-primary" id="close-record">关闭录像</button>
<!-- <button type="button" class="btn btn-outline-primary" id="close-record">录像下载接口</button> --> <!-- <button type="button" class="btn btn-outline-primary" id="close-record">录像下载接口</button> -->
@ -105,7 +114,7 @@
<script type="module"> <script type="module">
//获取参数real //获取参数real
let isReal = window.location.href.indexOf('real') !== -1 ? true : false; let isReal = window.location.href.indexOf('real') !== -1 ? true : false;
if(isReal){ if (isReal) {
document.getElementsByClassName('record-container')[0].style.display = 'none'; document.getElementsByClassName('record-container')[0].style.display = 'none';
document.getElementById('real-title').style.display = 'none'; document.getElementById('real-title').style.display = 'none';
document.getElementById('real-btn-box').style.display = 'none'; document.getElementById('real-btn-box').style.display = 'none';
@ -122,15 +131,15 @@
let cameraInfo; let cameraInfo;
let recordInfo; let recordInfo;
//接收消息 //接收消息
window.addEventListener('message', function(event) { window.addEventListener('message', function (event) {
console.log('接收到消息:', event.data); console.log('接收到消息:', event.data);
if (event.data === 'reload') { if (event.data === 'reload') {
location.reload() location.reload()
}else if (event.data.type ==='startVideo') { } else if (event.data.type === 'startVideo') {
cameraInfo = event.data.data; cameraInfo = event.data.data;
playReal() playReal()
} }
else if (event.data.type ==='playRecord') { else if (event.data.type === 'playRecord') {
recordInfo = event.data.data; recordInfo = event.data.data;
playRecord() playRecord()
} }
@ -178,11 +187,11 @@
showControl: true, /** 是否显示工具栏,默认显示 **/ showControl: true, /** 是否显示工具栏,默认显示 **/
prefixUrl: 'dahua/lib', /** 解码库所在位置的前缀 **/ prefixUrl: 'dahua/lib', /** 解码库所在位置的前缀 **/
receiveMessageFromWSPlayer: (methods, data, err) => { /* 回调函数,可以在以下回调函数里面做监听 */ receiveMessageFromWSPlayer: (methods, data, err) => { /* 回调函数,可以在以下回调函数里面做监听 */
switch(methods) { switch (methods) {
case 'initializationCompleted': case 'initializationCompleted':
console.log('初始化完成') console.log('初始化完成')
realPlayer.setPlayerAdapter("stretching") realPlayer.setPlayerAdapter("stretching")
if(isReal) window.parent.postMessage({type: 'startVideo'}, '*') if (isReal) window.parent.postMessage({ type: 'startVideo' }, '*')
// playReal() // playReal()
// 初始化完成,可调用播放方法(适用于动态加载解码库) // 初始化完成,可调用播放方法(适用于动态加载解码库)
// 若回调未触发时就使用实时预览/录像回放,则无法播放。 // 若回调未触发时就使用实时预览/录像回放,则无法播放。
@ -194,6 +203,7 @@
console.log(data.selectIndex) // 窗口序号,从 0 console.log(data.selectIndex) // 窗口序号,从 0
break; break;
case "realSuccess": // 实时预览成功 case "realSuccess": // 实时预览成功
window.parent.postMessage({type: 'realSuccess'}, '*')
console.log("实时预览成功") console.log("实时预览成功")
break; break;
case "realError": // 实时预览失败 case "realError": // 实时预览失败
@ -214,7 +224,7 @@
case 'closeVideo': // 视频关闭回调 case 'closeVideo': // 视频关闭回调
// 点击关闭按钮引发的视频关闭进行提示 // 点击关闭按钮引发的视频关闭进行提示
// 切换视频引发的视频关闭不进行提示 // 切换视频引发的视频关闭不进行提示
if(!data.changeVideoFlag) { if (!data.changeVideoFlag) {
console.log(`窗口${data.selectIndex}的视频已关闭`) console.log(`窗口${data.selectIndex}的视频已关闭`)
} }
break; break;
@ -286,7 +296,7 @@
showControl: true, /** 是否显示工具栏,默认显示 **/ showControl: true, /** 是否显示工具栏,默认显示 **/
prefixUrl: 'dahua/lib', /** 解码库所在位置的前缀 **/ prefixUrl: 'dahua/lib', /** 解码库所在位置的前缀 **/
receiveMessageFromWSPlayer: (methods, data, err) => { /* 回调函数,可以在以下回调函数里面做监听 */ receiveMessageFromWSPlayer: (methods, data, err) => { /* 回调函数,可以在以下回调函数里面做监听 */
switch(methods) { switch (methods) {
case 'initializationCompleted': case 'initializationCompleted':
// 初始化完成,可以调用拉流方法,实现播放器加载后立即显示画面 // 初始化完成,可以调用拉流方法,实现播放器加载后立即显示画面
break; break;
@ -322,7 +332,7 @@
case 'closeVideo': // 视频关闭回调 case 'closeVideo': // 视频关闭回调
// 点击关闭按钮引发的视频关闭进行提示 // 点击关闭按钮引发的视频关闭进行提示
// 切换视频引发的视频关闭不进行提示 // 切换视频引发的视频关闭不进行提示
if(!data.changeVideoFlag) { if (!data.changeVideoFlag) {
console.log(`窗口${data.selectIndex}的视频已关闭`) console.log(`窗口${data.selectIndex}的视频已关闭`)
} }
break; break;
@ -375,7 +385,7 @@
getDom('#real-btn').addEventListener('click', () => { getDom('#real-btn').addEventListener('click', () => {
//向父窗口发送消息 //向父窗口发送消息
window.parent.postMessage({type: 'startVideo'}, '*') window.parent.postMessage({ type: 'startVideo' }, '*')
// playReal() // playReal()
}) })
// getDom('#talk-btn').addEventListener('click', () => { // getDom('#talk-btn').addEventListener('click', () => {
@ -387,7 +397,7 @@
// }) // })
getDom('#record-btn').addEventListener('click', () => { getDom('#record-btn').addEventListener('click', () => {
let date = getDom('#date').value; let date = getDom('#date').value;
window.parent.postMessage({type:'playRecord',date}, '*') window.parent.postMessage({ type: 'playRecord', date }, '*')
// playRecord() // playRecord()
}) })
getDom('#close-real').addEventListener('click', e => { getDom('#close-real').addEventListener('click', e => {
@ -405,8 +415,8 @@
platform: '4077', platform: '4077',
realPort: isHttp ? '4079' : '4081', realPort: isHttp ? '4079' : '4081',
recordPort: isHttp ? '4080' : '4082', recordPort: isHttp ? '4080' : '4082',
real_wsUrl: `${isHttp ? 'ws': 'wss'}://124.160.33.135:${isHttp ? '4079' : '4081'}`, // 实时预览ws地址 real_wsUrl: `${isHttp ? 'ws' : 'wss'}://124.160.33.135:${isHttp ? '4079' : '4081'}`, // 实时预览ws地址
record_wsUrl: `${isHttp ? 'ws': 'wss'}://124.160.33.135:${isHttp ? '4080' : '4082'}` record_wsUrl: `${isHttp ? 'ws' : 'wss'}://124.160.33.135:${isHttp ? '4080' : '4082'}`
} }
ipDom.value = wsplayerParam.ip ipDom.value = wsplayerParam.ip
platformDom.value = wsplayerParam.platform platformDom.value = wsplayerParam.platform
@ -422,8 +432,8 @@
platform: platformDom.value, platform: platformDom.value,
realPort: realPortDom.value, realPort: realPortDom.value,
recordPort: recordPortDom.value, recordPort: recordPortDom.value,
real_wsUrl: `${isHttp ? 'ws://': 'wss://'}${ipDom.value}:${realPortDom.value}`, // 实时预览ws地址 real_wsUrl: `${isHttp ? 'ws://' : 'wss://'}${ipDom.value}:${realPortDom.value}`, // 实时预览ws地址
record_wsUrl: `${isHttp ? 'ws://': 'wss://'}${ipDom.value}:${recordPortDom.value}` record_wsUrl: `${isHttp ? 'ws://' : 'wss://'}${ipDom.value}:${recordPortDom.value}`
} }
localStorage.wsplayerParam = JSON.stringify(wsplayerParam) localStorage.wsplayerParam = JSON.stringify(wsplayerParam)
renderDom() renderDom()
@ -451,4 +461,5 @@
</script> </script>
</body> </body>
</html> </html>

@ -109,7 +109,7 @@
<div class="center-top-item"> <div class="center-top-item">
<div class="boxtitle changtitle">视频监控</div> <div class="boxtitle changtitle">视频监控</div>
<div class="center-item bigbj"> <div class="center-item bigbj">
<myVideo></myVideo> <myVideo ref="myVideoRef"></myVideo>
<!-- <div class="alarm-table-header"> <!-- <div class="alarm-table-header">
<div>序号</div> <div>序号</div>
<div>姓名</div> <div>姓名</div>
@ -333,142 +333,7 @@ const state = reactive({
echartsZhu, echartsZhu,
echart, echart,
loading: true, loading: true,
tableData: [{ tableData: [],
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 1,
openType: 43,
startSwingTime: "2025-05-13 02:17:55",
maskState: 3,
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 2,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
maskState: 2
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 1,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 1,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 2,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 1,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
}, {
"id": 17,
"personId": 21059,
"personCode": "112325",
"personName": "小高测试用例1",
"departmentId": 53,
"deptName": "小高测试用例部门1",
"cardNo": "40D3989B",
"siteId": "1",
"siteName": "门禁测试",
"attendanceType": "51",
"actionTime": "2023-08-24 02:17:55",
"reportTime": "2023-08-24 02:17:56",
"dataSource": 1,
"supplementFormId": null,
"number": null,
imageType: 1,
openType: 42,
startSwingTime: "2025-05-13 02:17:55",
}],
warnList: [], warnList: [],
monitorList: [], monitorList: [],
logList: [], logList: [],
@ -483,6 +348,7 @@ const state = reactive({
requestController: null, requestController: null,
time: null, time: null,
}) })
const myVideoRef = ref()
onUnmounted(() => { onUnmounted(() => {
if (state.requestController) state.requestController.stop(); if (state.requestController) state.requestController.stop();
}); });
@ -519,6 +385,9 @@ onMounted(async () => {
return res; return res;
} }
state.requestController = retryAndRepeatRequest(requestFn, 3, 30000, 300000); state.requestController = retryAndRepeatRequest(requestFn, 3, 30000, 300000);
// nextTick(() => {
// myVideoRef.value.getList()
// })
state.loading = false state.loading = false
}) })
function getTime() { function getTime() {
@ -599,7 +468,7 @@ function getQuerywarn(params) {
// //
function accessControl() { function accessControl() {
getRecordPage().then((res) => { getRecordPage().then((res) => {
// state.tableData = res.data.pageData state.tableData = res.data.pageData
}) })
} }
// //

@ -2,11 +2,11 @@
import { reactive, onMounted } from 'vue' import { reactive, onMounted } from 'vue'
import { getRtspUrl, getDevicePage, getPlaybackByTimeRtspUrl, getRegularVideoRecords } from './api' import { getRtspUrl, getDevicePage, getPlaybackByTimeRtspUrl, getRegularVideoRecords } from './api'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
const state = reactive({ const state = reactive({
currentCameraIndex: 0, currentCameraIndex: 0,
cameraList: [], cameraList: [],
cameraInfo: null cameraInfo: null,
isShow: false
}) })
const switchCamera = (index) => { const switchCamera = (index) => {
state.currentCameraIndex = index; state.currentCameraIndex = index;
@ -99,29 +99,34 @@ const playRecord = (date) => {
}) })
} }
onMounted(() => { function getList() {
}
onMounted(async () => {
getDevicePage({ getDevicePage({
"pageNum": 1, "pageNum": 1,
"pageSize": 100, "pageSize": 100,
}).then((res) => { }).then((res) => {
state.cameraList = res.data.pageData state.cameraList = res.data.pageData
const index = state.cameraList.findIndex(item => item.isOnline === 1); const index = state.cameraList.findIndex(item => item.isOnline == 1);
state.currentCameraIndex = index state.currentCameraIndex = index
}).catch((err) => { }).catch((err) => {
}); });
// //
window.addEventListener('message', (event) => { window.addEventListener('message', (event) => {
console.log('event :>> ', event.data); console.log('event :>> ', event.data);
if (event.data.type === 'startVideo') { if (event.data.type === 'startVideo') {
startVideo(); startVideo();
} else if (event.data.type === 'playRecord') { } else if (event.data.type === 'playRecord') {
playRecord(event.data.date); playRecord(event.data.date);
} else if (event.data.type == "realSuccess") {
state.isShow = true
} }
}); });
}) })
defineExpose({
getList
});
</script> </script>
<template> <template>
@ -145,11 +150,13 @@ onMounted(() => {
</template> --> </template> -->
</div> </div>
<!-- 摄像头展示区域 --> <!-- 摄像头展示区域 -->
<div class="camera-display"> <div class="camera-display" v-show="state.isShow">
<iframe v-if="state.cameraList.length > 0" id="video" src="/dahua/demo.html?real=true" <iframe v-if="state.cameraList.length > 0" id="video" src="/dahua/demo.html?real=true"
style="width:100%;height:100%;" frameborder="0"></iframe> style="width:100%;height:100%;" frameborder="0"></iframe>
</div> </div>
<div v-show="!state.isShow" element-loading-background="black" element-loading-text="正在加载中..." v-loading="!state.isShow" class="camera-display">
</div>
</div> </div>
</template> </template>

@ -58,6 +58,10 @@ color: #333333;">用户登录</div>
</div> --> </div> -->
</el-form-item> </el-form-item>
</el-form> </el-form>
<div style="display: none;">
<img width="100px" src="../assets/images/videoitembj.png" alt="">
<img width="100px" src="../assets/images/videoitembjtwo.png" alt="">
</div>
<!-- 底部 --> <!-- 底部 -->
</div> </div>
</template> </template>

Loading…
Cancel
Save