feat:新增视频操作
@@ -35,3 +35,12 @@ export function postVideoRemainApi(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据监控点编号进行云台操作
|
||||||
|
export function postVideoControlApi(data) {
|
||||||
|
return request({
|
||||||
|
url: '/fjtcc-api/api/largeScreen/video/controlling',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ instance.interceptors.response.use(
|
|||||||
if (res.data.code == 200) {
|
if (res.data.code == 200) {
|
||||||
return res.data
|
return res.data
|
||||||
} else {
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
return Promise.reject(res.data)
|
return Promise.reject(res.data)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
src/assets/images/down.png
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
src/assets/images/left.png
Normal file
|
After Width: | Height: | Size: 436 B |
BIN
src/assets/images/minus.png
Normal file
|
After Width: | Height: | Size: 795 B |
BIN
src/assets/images/pause.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/images/plus.png
Normal file
|
After Width: | Height: | Size: 863 B |
BIN
src/assets/images/right.png
Normal file
|
After Width: | Height: | Size: 404 B |
BIN
src/assets/images/up.png
Normal file
|
After Width: | Height: | Size: 483 B |
@@ -27,7 +27,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<video-dialog v-model="videoShow" :src="src" />
|
<video-dialog v-model="videoShow" :src="src" :cameraIndexCode="cameraIndexCode" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -38,10 +38,12 @@
|
|||||||
|
|
||||||
let list = ref([])
|
let list = ref([])
|
||||||
let src = ref('')
|
let src = ref('')
|
||||||
|
let cameraIndexCode = ref('')
|
||||||
let videoShow = ref(false)
|
let videoShow = ref(false)
|
||||||
|
|
||||||
const handleItem = (item) => {
|
const handleItem = (item) => {
|
||||||
src.value = item.hlsUrl
|
src.value = item.hlsUrl
|
||||||
|
cameraIndexCode.value = item.cameraIndexCode
|
||||||
videoShow.value = true
|
videoShow.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,6 @@
|
|||||||
isSkip.value = false
|
isSkip.value = false
|
||||||
isBack.value = true
|
isBack.value = true
|
||||||
let res = await getSpotListApi()
|
let res = await getSpotListApi()
|
||||||
console.log(res, '============')
|
|
||||||
navLeft.value = res.data
|
navLeft.value = res.data
|
||||||
current.value = 0
|
current.value = 0
|
||||||
title.value = navLeft.value[current.value].name
|
title.value = navLeft.value[current.value].name
|
||||||
@@ -196,6 +195,8 @@
|
|||||||
case '/monitor':
|
case '/monitor':
|
||||||
title.value = '监控大屏'
|
title.value = '监控大屏'
|
||||||
isSkip.value = false
|
isSkip.value = false
|
||||||
|
current.vlaue = ''
|
||||||
|
isBack.value = true
|
||||||
let res1 = await getSpotListApi()
|
let res1 = await getSpotListApi()
|
||||||
navLeft.value = [
|
navLeft.value = [
|
||||||
{
|
{
|
||||||
@@ -204,8 +205,6 @@
|
|||||||
},
|
},
|
||||||
...res1.data
|
...res1.data
|
||||||
]
|
]
|
||||||
current.vlaue = ''
|
|
||||||
isBack.value = true
|
|
||||||
break
|
break
|
||||||
case '/sceneTesting':
|
case '/sceneTesting':
|
||||||
title.value = '三峡之巅-安全检测'
|
title.value = '三峡之巅-安全检测'
|
||||||
|
|||||||
@@ -1,30 +1,65 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<el-dialog v-model="modelValue" align-center :modal="false" :show-close="false">
|
<el-dialog v-model="modelValue" align-center :modal="false" :show-close="false" z-index="9999">
|
||||||
<video
|
<div v-if="src">
|
||||||
v-if="src"
|
<video class="video" ref="videoRef" muted autoplay controls style="object-fit: cover">
|
||||||
class="video"
|
<source src="" type="application/x-mpegURL" />
|
||||||
ref="videoRef"
|
</video>
|
||||||
muted
|
<div class="action-box">
|
||||||
autoplay
|
<!-- <div class="action-item">
|
||||||
controls
|
<img src="@/assets/images/plus.png" alt="" />
|
||||||
style="object-fit: cover"
|
<span>变倍</span>
|
||||||
>
|
<img src="@/assets/images/minus.png" alt="" />
|
||||||
<source src="" type="application/x-mpegURL" />
|
</div> -->
|
||||||
</video>
|
<div class="action-item">
|
||||||
|
<img src="@/assets/images/plus.png" title="焦距变大" @click="handleAction(Z00M_IN)" />
|
||||||
|
<span>聚焦</span>
|
||||||
|
<img src="@/assets/images/minus.png" title="焦距变小" @click="handleAction(Z00M_OUT)" />
|
||||||
|
</div>
|
||||||
|
<div class="action-item">
|
||||||
|
<img src="@/assets/images/up.png" title="上转" @click="handleAction(UP)" />
|
||||||
|
<img src="@/assets/images/down.png" title="下转" @click="handleAction(DOWN)" />
|
||||||
|
<img
|
||||||
|
class="pause"
|
||||||
|
src="@/assets/images/pause.png"
|
||||||
|
title="停止操作"
|
||||||
|
@click="handleAction(STOP)"
|
||||||
|
/>
|
||||||
|
<img src="@/assets/images/left.png" title="左转" @click="handleAction(LEFT)" />
|
||||||
|
<img src="@/assets/images/right.png" title="右转" @click="handleAction(RIGHT)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<p v-else class="none">暂无信号</p>
|
<p v-else class="none">暂无信号</p>
|
||||||
<img class="close" src="@/assets/images/close.png" @click="modelValue = false" />
|
<img class="close" src="@/assets/images/close.png" @click="handleClose" />
|
||||||
|
<div></div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Hls from 'hls.js'
|
import Hls from 'hls.js'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
import { postVideoControlApi } from '@/api/monitor'
|
||||||
|
|
||||||
|
const Z00M_IN = 'ZOOM_IN' // 焦距变大
|
||||||
|
const Z00M_OUT = 'ZOOM_OUT' // 焦距变小
|
||||||
|
const ACTION = '0'
|
||||||
|
const UP = 'UP' // 上转
|
||||||
|
const DOWN = 'DOWN' // 下转
|
||||||
|
const LEFT = 'LEFT' // 左转
|
||||||
|
const RIGHT = 'RIGHT' // 右转
|
||||||
|
const STOP = 'STOP' // 停止操作
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
src: {
|
src: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
cameraIndexCode: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -45,6 +80,25 @@
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleAction = async (e) => {
|
||||||
|
if (e == STOP) {
|
||||||
|
ACTION = '1'
|
||||||
|
} else {
|
||||||
|
ACTION = '0'
|
||||||
|
}
|
||||||
|
await postVideoControlApi({
|
||||||
|
command: e,
|
||||||
|
action: ACTION,
|
||||||
|
cameraIndexCode: props.cameraIndexCode
|
||||||
|
})
|
||||||
|
ElMessage({
|
||||||
|
message: '操作成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleClose = () => {
|
||||||
|
modelValue.value = false
|
||||||
|
}
|
||||||
const init = () => {
|
const init = () => {
|
||||||
const hls = new Hls({
|
const hls = new Hls({
|
||||||
maxBufferLength: 10, // 最大缓冲长度(秒)
|
maxBufferLength: 10, // 最大缓冲长度(秒)
|
||||||
@@ -62,6 +116,36 @@
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.dialog {
|
.dialog {
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
.action {
|
||||||
|
&-box {
|
||||||
|
margin-top: vh(16);
|
||||||
|
gap: vw(20);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
&-item {
|
||||||
|
padding: vw(16);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #0a4190;
|
||||||
|
border-radius: vw(8);
|
||||||
|
> img {
|
||||||
|
cursor: pointer;
|
||||||
|
width: vw(34);
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
> span {
|
||||||
|
margin: 0 vw(16);
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: vw(16);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
.pause {
|
||||||
|
margin: 0 vw(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.none {
|
.none {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
@@ -75,7 +159,6 @@
|
|||||||
:deep(.el-dialog) {
|
:deep(.el-dialog) {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: vw(1660);
|
width: vw(1660);
|
||||||
height: vw(980);
|
|
||||||
padding: vw(40) vw(30) vw(30) vw(30);
|
padding: vw(40) vw(30) vw(30) vw(30);
|
||||||
background-image: url('@/assets/images/one-video-bg.png');
|
background-image: url('@/assets/images/one-video-bg.png');
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import router from './router'
|
|||||||
import '@/styles/reset.css'
|
import '@/styles/reset.css'
|
||||||
import '@/styles/common.scss'
|
import '@/styles/common.scss'
|
||||||
import '@/assets/fonts/index.css'
|
import '@/assets/fonts/index.css'
|
||||||
|
import 'element-plus/theme-chalk/el-message-box.css'
|
||||||
|
import 'element-plus/theme-chalk/el-message.css'
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.select-box {
|
.select-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 9999;
|
z-index: 99;
|
||||||
top: vh(40);
|
top: vh(40);
|
||||||
right: vw(10);
|
right: vw(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.select-box {
|
.select-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 9999;
|
z-index: 99;
|
||||||
top: vh(10);
|
top: vh(10);
|
||||||
right: vw(10);
|
right: vw(10);
|
||||||
}
|
}
|
||||||
|
|||||||