feat(deviceManagement): 视频设备管理增加监控调试功能

- 添加监控调试按钮并实现相关功能- 新增 MonitoringAndDebug 组件用于监控调试界面
- 实现视频播放、云台控制、水印设置等功能
- 添加快捷键设置并支持键盘事件监听
This commit is contained in:
jjLv 2025-01-21 13:41:56 +08:00
parent 967768d96d
commit 57c4742c99
2 changed files with 414 additions and 1 deletions

View File

@ -73,7 +73,7 @@
<!-- 操作 -->
<el-table-column label="操作" align="center" width="255">
<template slot-scope="scope">
<el-button type="warning" plain size="mini" icon="el-icon-set-up" @click="">调试</el-button>
<el-button type="warning" plain size="mini" icon="el-icon-set-up" @click="handleMonitoringAndDebug(scope.row)">调试</el-button>
<el-button type="primary" plain size="mini" icon="el-icon-edit" @click="handleEdit(scope.row)">
编辑
</el-button>
@ -177,15 +177,23 @@
<el-button type="primary" @click="downloadQrCode" style="margin-top: 20px"> </el-button>
</div>
</el-dialog>
<el-dialog title="调试" :visible.sync="videoDebug" width="70%" height="80%">
<MonitoringAndDebug />
</el-dialog>
</div>
</template>
<script>
import VueQr from 'vue-qr'
import MonitoringAndDebug from '@/views/deviceManagement/videoDeviceMgmt/monitoringAndDebug.vue';
export default {
components: {
VueQr,
MonitoringAndDebug
},
data() {
return {
@ -244,6 +252,7 @@ export default {
},
],
qrVisible: false,
videoDebug: false,
qrData: {
qrCode: '',
deviceNo: '',
@ -393,6 +402,11 @@ export default {
this.$refs.dialogForm.clearValidate()
})
},
//
handleMonitoringAndDebug(row) {
console.log('监控调试', row)
this.videoDebug = true
},
//
handleDetail(row) {
console.log('查看配置', row)

View File

@ -0,0 +1,399 @@
<template>
<div class="monitor-page">
<!-- 左侧视频监控区 -->
<div class="video-section">
<div class="video-title">视频播放</div>
<div class="video-container">
<div class="video-overlay">
<div class="timestamp">{{ currentTime }}</div>
<div class="coordinates">
<div>{{ coordinates.line1 }}</div>
<div>{{ coordinates.line2 }}</div>
</div>
<div class="signal-info">电池: {{ batteryInfo }}</div>
</div>
</div>
</div>
<!-- 右侧控制区 -->
<div class="control-section">
<!-- 调试云台 -->
<div class="control-title">调试云台</div>
<!-- 方向控制 -->
<div class="direction-control">
<div class="direction-pad">
<el-button class="btn-up" @click="control('up')">
<i class="el-icon-arrow-up"></i>
</el-button>
<div class="horizontal-buttons">
<el-button class="btn-left" @click="control('left')">
<i class="el-icon-arrow-left"></i>
</el-button>
<el-button class="btn-right" @click="control('right')">
<i class="el-icon-arrow-right"></i>
</el-button>
</div>
<el-button class="btn-down" @click="control('down')">
<i class="el-icon-arrow-down"></i>
</el-button>
</div>
<!-- 缩放控制 -->
<div class="zoom-controls">
<div class="zoom-column">
<el-button @click="control('zoomIn')">
<i class="el-icon-plus"></i>
</el-button>
<el-button @click="control('zoomOut')">
<i class="el-icon-minus"></i>
</el-button>
<div class="column-label">聚焦</div>
</div>
<div class="zoom-column">
<el-button @click="control('focusIn')">
<i class="el-icon-plus"></i>
</el-button>
<el-button @click="control('focusOut')">
<i class="el-icon-minus"></i>
</el-button>
<div class="column-label">缩放</div>
</div>
<div class="zoom-column">
<el-button @click="control('lightUp')">
<i class="el-icon-plus"></i>
</el-button>
<el-button @click="control('lightDown')">
<i class="el-icon-minus"></i>
</el-button>
<div class="column-label">光圈</div>
</div>
</div>
</div>
<!-- 视图切换按钮组 -->
<div class="view-controls">
<div class="view-row">
<div class="view-item">
<i class="el-icon-video-camera"></i>
<span>本地录像</span>
</div>
<div class="view-item">
<i class="el-icon-picture"></i>
<span>本地抓拍</span>
</div>
</div>
<div class="view-row">
<div class="view-item">
<i class="el-icon-video-camera"></i>
<span>远程录像</span>
</div>
<div class="view-item">
<i class="el-icon-picture"></i>
<span>远程抓拍</span>
</div>
</div>
</div>
<div class="control-title">3D云台控制</div>
<!-- 3D云台控制 -->
<div class="cloud-control">
<div class="cloud-buttons">
<el-button @click="toggleCloud">关闭云台</el-button>
<el-button @click="startCloud">开启云台</el-button>
</div>
</div>
<div class="control-title">水印设置</div>
<!-- 水印设置 -->
<div class="watermark-section">
<div class="watermark-title">应用水印<i class="el-icon-s-operation"></i></div>
<el-input
v-model="watermark.line1"
placeholder="设置第一行视频水印文字"
></el-input>
<el-input
v-model="watermark.line2"
placeholder="设置第二行视频水印文字"
></el-input>
</div>
<div class="control-title">快捷键设置</div>
<!-- 快捷键设置 -->
<div class="shortcut-section">
<div class="shortcut-grid">
<div class="shortcut-row" v-for="(row, rowIndex) in shortcutSettings" :key="rowIndex">
<div class="shortcut-item" v-for="(item, colIndex) in row" :key="colIndex">
<span>{{item.label}}</span>
<input
v-model="item.key"
@keydown.native="handleKeyPress($event, rowIndex, colIndex)"
:maxlength="1"
class="key"
></input>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'VideoMonitor',
data() {
return {
currentTime: '2023-01-07 13:19:38',
coordinates: {
line1: '116.13263L 000KPH',
line2: '033.50462N 000D/G'
},
batteryInfo: '64% 4G1:96% 4G2:96%',
watermark: {
line1: '',
line2: ''
},
keyMap: {
'w': 'up',
's': 'down',
'a': 'left',
'd': 'right',
'q': 'zoomIn',
'e': 'zoomOut',
'r': 'focusIn',
't': 'focusOut',
'f': 'capture',
'g': 'record'
},
//
shortcutSettings: [
[
{ label: '上', key: 'W' },
{ label: '放大', key: 'Q' }
],
[
{ label: '下', key: 'S' },
{ label: '缩小', key: 'E' }
],
[
{ label: '左', key: 'A' },
{ label: '远焦', key: 'R' }
],
[
{ label: '右', key: 'D' },
{ label: '近焦', key: 'T' }
],
[
{ label: '抓拍', key: 'F' },
{ label: '录像', key: 'G' }
]
]
}
},
methods: {
control(action) {
console.log('Control action:', action)
},
toggleCloud() {
console.log('Toggle cloud platform')
},
startCloud() {
console.log('Start cloud platform')
},
//
handleKeyPress(event, rowIndex, colIndex) {
event.preventDefault();
const key = event.key.toUpperCase();
//
if (/^[A-Z]$/.test(key)) {
this.shortcutSettings[rowIndex][colIndex].key = key;
}
}
},
mounted() {
//
window.addEventListener('keydown', (e) => {
if (this.keyMap[e.key]) {
this.control(this.keyMap[e.key])
}
})
}
}
</script>
<style scoped>
.monitor-page {
display: flex;
gap: 20px;
}
.video-section {
flex: 1;
display: flex;
flex-direction: column;
}
.control-section {
width: 300px;
background: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.video-title {
font-size: 16px;
margin-bottom: 10px;
padding: 10px;
background: white;
border-radius: 4px;
}
.video-container {
flex: 1;
position: relative;
background: black;
border-radius: 4px;
overflow: hidden;
}
.video-feed {
width: 100%;
height: 100%;
object-fit: contain;
}
.video-overlay {
position: absolute;
top: 10px;
right: 10px;
color: white;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}
.direction-control {
display: flex;
justify-content: space-between;
margin: 12px 0;
}
.direction-pad {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.horizontal-buttons {
display: flex;
gap: 5px;
}
.zoom-controls {
display: flex;
gap: 10px;
flex-direction: column;
}
.zoom-column {
display: flex;
flex-direction: row;
gap: 5px;
}
.cloud-control {
margin: 12px 0;
}
.cloud-buttons {
display: flex;
gap: 10px;
}
.view-controls {
margin: 12px 0;
}
.view-row {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.view-item {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}
.watermark-section {
margin: 12px 0;
}
.watermark-title{
font-size: 13px;
display: flex;
flex-direction: row-reverse;
align-items: center;
color: rgb(102, 177, 255);
}
.watermark-section .el-input {
margin-bottom: 10px;
}
.shortcut-section {
margin-top: 20px;
}
.shortcut-grid {
display: flex;
flex-direction: column;
gap: 10px;
}
.shortcut-row {
display: flex;
justify-content: space-between;
}
.shortcut-item {
display: flex;
justify-content: space-between;
align-items: center;
width: 45%;
background: #f5f7fa;
padding: 5px 10px;
border-radius: 4px;
}
.key {
width: 21px;
height: 21px;
border: 0px solid #DCDFE6;
background: #f5f7fa;
color: rgb(25, 190, 107);
font-weight: bold;
}
.control-title {
font-size: 14px;
font-family: "微软雅黑 Bold", "微软雅黑 Regular", 微软雅黑, sans-serif;
font-weight: 700;
font-style: normal;
color: rgb(102, 177, 255);
}
.el-button {
padding: 8px 15px;
}
.el-button [class^="el-icon-"] {
margin: 0;
}
</style>