feat(deviceManagement): 视频设备管理增加监控调试功能
- 添加监控调试按钮并实现相关功能- 新增 MonitoringAndDebug 组件用于监控调试界面 - 实现视频播放、云台控制、水印设置等功能 - 添加快捷键设置并支持键盘事件监听
This commit is contained in:
parent
967768d96d
commit
57c4742c99
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue