智感、智库-含视频组件的增加乐橙视频,且根据组件的需求修改增加功能
parent
f223377628
commit
5a09a108d6
|
|
@ -15,7 +15,12 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -127,8 +127,26 @@
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="videoItem.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="index + '-' + videoIndex"
|
:index="index + '-' + videoIndex"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -138,14 +156,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="videoItem.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 单个 -->
|
<!-- 单个 -->
|
||||||
|
|
@ -161,8 +171,26 @@
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && item.videos.videourl && !item.videos.manufacturer"
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="item.videos.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videos.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '腾讯'"
|
||||||
:videourl="item.videos.videourl"
|
:videourl="item.videos.videourl"
|
||||||
:index="index + '-0'"
|
:index="index + '-0'"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -172,14 +200,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="item.videos.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -198,7 +218,7 @@
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -311,7 +331,7 @@
|
||||||
|
|
||||||
.timeLineVideoDivTitle {
|
.timeLineVideoDivTitle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 100;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 25,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-25}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 25px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="optionData.dataStyle.serialNumberValue"
|
v-model:value="optionData.dataStyle.serialNumberValue"
|
||||||
:options="option.dataset"
|
:options="option.dataset"
|
||||||
label-field="name"
|
label-field="title"
|
||||||
value-field="serialNumber"
|
value-field="serialNumber"
|
||||||
placeholder="请选择默认视频"
|
placeholder="请选择默认视频"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -2,73 +2,79 @@
|
||||||
"source": [
|
"source": [
|
||||||
{
|
{
|
||||||
"id": 418015298064389,
|
"id": 418015298064389,
|
||||||
"name": "XZD148青山裕南山",
|
"title": "XZD148青山裕南山",
|
||||||
"serialNumber": "13b23c9b878143bc99269898964af54f",
|
"serialNumber": "13b23c9b878143bc99269898964af54f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349661701,
|
"id": 418015349661701,
|
||||||
"name": "XZD153狼窝沟西南",
|
"title": "XZD153狼窝沟西南",
|
||||||
"serialNumber": "74b95e6575d741489b9a9061bb646467",
|
"serialNumber": "74b95e6575d741489b9a9061bb646467",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349899269,
|
"id": 418015349899269,
|
||||||
"name": "XZD152青山裕水库东",
|
"title": "XZD152青山裕水库东",
|
||||||
"serialNumber": "ecdb49050c57452dbae7ec6f03e82667",
|
"serialNumber": "ecdb49050c57452dbae7ec6f03e82667",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015350452229,
|
"id": 418015350452229,
|
||||||
"name": "XZD147大古台南山",
|
"title": "XZD147大古台南山",
|
||||||
"serialNumber": "edd84ccac34441c48c6a7bf030f9c13f",
|
"serialNumber": "edd84ccac34441c48c6a7bf030f9c13f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351681029,
|
"id": 418015351681029,
|
||||||
"name": "XZD151青山裕水库西",
|
"title": "XZD151青山裕水库西",
|
||||||
"serialNumber": "c10f9faea87d4f659e2bc01de24e29a9",
|
"serialNumber": "c10f9faea87d4f659e2bc01de24e29a9",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351836677,
|
"id": 418015351836677,
|
||||||
"name": "XZD149青山裕北山",
|
"title": "XZD149青山裕北山",
|
||||||
"serialNumber": "909e98d192f649fea4c5269f5f7832e1",
|
"serialNumber": "909e98d192f649fea4c5269f5f7832e1",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351025669,
|
"id": 418015351025669,
|
||||||
"name": "XZD150青山裕山里人家西北",
|
"title": "XZD150青山裕山里人家西北",
|
||||||
"serialNumber": "b56f09f8c64249379e42481c7b173dce",
|
"serialNumber": "b56f09f8c64249379e42481c7b173dce",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976901,
|
"id": 490483936976901,
|
||||||
"name": "XZD155突围路广场",
|
"title": "XZD155突围路广场",
|
||||||
"serialNumber": "a8010ac49baa4b81a569ba24dc95a4e7",
|
"serialNumber": "a8010ac49baa4b81a569ba24dc95a4e7",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976911,
|
"id": 490483936976911,
|
||||||
"name": "playerVideo",
|
"title": "大青山林场机库摄像头",
|
||||||
|
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-fc4c09b5a3451bb9.flv",
|
||||||
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 490483936976911,
|
||||||
|
"title": "玉皇宫机库摄像头",
|
||||||
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"serialNumber": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976912,
|
"id": 490483936976912,
|
||||||
"name": "店子分区",
|
"title": "店子分区",
|
||||||
"serialNumber": "8H03AA1PAGDC8C3",
|
"serialNumber": "8H03AA1PAGDC8C3",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976913,
|
"id": 490483936976913,
|
||||||
"name": "白马关通天沟",
|
"title": "白马关通天沟",
|
||||||
"serialNumber": "8H03AA1PAG97234",
|
"serialNumber": "8H03AA1PAG97234",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976914,
|
"id": 490483936976914,
|
||||||
"name": "后白崖",
|
"title": "后白崖",
|
||||||
"serialNumber": "8H03AA1PAGF203B",
|
"serialNumber": "8H03AA1PAGF203B",
|
||||||
"manufacturer": "乐橙"
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button>
|
<n-button>
|
||||||
<span
|
<span
|
||||||
calss="modalTitle_name"
|
calss="modalTitle_title"
|
||||||
:style="{
|
:style="{
|
||||||
color: option.dataStyle.titleFontColor,
|
color: option.dataStyle.titleFontColor,
|
||||||
fontSize: option.dataStyle.titleFontSize + 'px',
|
fontSize: option.dataStyle.titleFontSize + 'px',
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="option.dataStyle.serialNumberValue"
|
v-model:value="option.dataStyle.serialNumberValue"
|
||||||
:options="option.dataset"
|
:options="option.dataset"
|
||||||
label-field="name"
|
label-field="title"
|
||||||
value-field="serialNumber"
|
value-field="serialNumber"
|
||||||
placeholder="请选择查看的视频"
|
placeholder="请选择查看的视频"
|
||||||
/>
|
/>
|
||||||
|
|
@ -49,10 +49,11 @@
|
||||||
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorTX
|
||||||
ref="PlayVideoRef"
|
ref="MonitorTXRef"
|
||||||
v-if="!isEdit && !manufacturer"
|
v-if="!isEdit && manufacturer == '腾讯'"
|
||||||
:serialNumberValue="option.dataStyle.serialNumberValue"
|
:serialNumberValue="option.dataStyle.serialNumberValue"
|
||||||
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:width="`${w - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
:height="`${h - option.dataStyle.modalTitleHeight - 2 * option.dataStyle.padding - 2 * option.dataStyle.borderWidth}`"
|
||||||
|
|
@ -84,7 +85,7 @@
|
||||||
import { EventBus } from '@/utils/eventBus';
|
import { EventBus } from '@/utils/eventBus';
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MonitorHK, MonitorLC, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -107,8 +108,8 @@
|
||||||
const MonitorHKRef = ref();
|
const MonitorHKRef = ref();
|
||||||
// 乐橙
|
// 乐橙
|
||||||
const MonitorLCRef = ref();
|
const MonitorLCRef = ref();
|
||||||
// 其他
|
// 腾讯
|
||||||
const PlayVideoRef = ref();
|
const MonitorTXRef = ref();
|
||||||
|
|
||||||
// 是否是编辑状态
|
// 是否是编辑状态
|
||||||
const isEdit = window.location.href.includes('/chart/home/');
|
const isEdit = window.location.href.includes('/chart/home/');
|
||||||
|
|
@ -136,7 +137,7 @@
|
||||||
() => option.dataStyle.serialNumberValue,
|
() => option.dataStyle.serialNumberValue,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
let data = getDataBySerialNumberValue(newValue);
|
let data = getDataBySerialNumberValue(newValue);
|
||||||
titleName.value = data.name;
|
titleName.value = data.title;
|
||||||
manufacturer.value = data.manufacturer;
|
manufacturer.value = data.manufacturer;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
@ -157,7 +158,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = getDataBySerialNumberValue(option.dataStyle.serialNumberValue);
|
let data = getDataBySerialNumberValue(option.dataStyle.serialNumberValue);
|
||||||
titleName.value = data.name;
|
titleName.value = data.title;
|
||||||
manufacturer.value = data.manufacturer;
|
manufacturer.value = data.manufacturer;
|
||||||
|
|
||||||
// 组件通信
|
// 组件通信
|
||||||
|
|
@ -208,7 +209,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
|
|
||||||
.modalTitle_name {
|
.modalTitle_title {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: v-bind('`${option.dataStyle.modalTitleHeight}px`');
|
height: v-bind('`${option.dataStyle.modalTitleHeight}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import MonitorHK from './monitorHK.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import MonitorLC from './monitorLC.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MonitorHK,
|
MonitorHK,
|
||||||
MonitorLC,
|
MonitorLC,
|
||||||
PlayVideo,
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -132,24 +132,9 @@
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 实际宽高
|
// 重定大小
|
||||||
let width = props.width;
|
reSizeVideo();
|
||||||
let height = props.height;
|
|
||||||
const divElement = document.getElementById('camera-box');
|
|
||||||
if (divElement) {
|
|
||||||
const rect = divElement.getBoundingClientRect();
|
|
||||||
const rectWidth = rect.width;
|
|
||||||
const rectHeight = rect.height;
|
|
||||||
if (rectWidth < width) {
|
|
||||||
width = rectWidth;
|
|
||||||
}
|
|
||||||
if (rectHeight < height) {
|
|
||||||
height = rectHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 开始预览多个视频
|
// 开始预览多个视频
|
||||||
oWebControl.JS_RequestInterface({
|
oWebControl.JS_RequestInterface({
|
||||||
funcName: 'startPreview',
|
funcName: 'startPreview',
|
||||||
|
|
@ -176,6 +161,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重定大小
|
||||||
|
function reSizeVideo() {
|
||||||
|
// 实际宽高
|
||||||
|
let width = props.width;
|
||||||
|
let height = props.height;
|
||||||
|
const divElement = document.getElementById('camera-box');
|
||||||
|
if (divElement) {
|
||||||
|
const rect = divElement.getBoundingClientRect();
|
||||||
|
const rectWidth = rect.width;
|
||||||
|
const rectHeight = rect.height;
|
||||||
|
if (rectWidth < width) {
|
||||||
|
width = rectWidth;
|
||||||
|
}
|
||||||
|
if (rectHeight < height) {
|
||||||
|
height = rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.serialNumberValue,
|
() => props.serialNumberValue,
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -212,10 +217,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_ModalVideo');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,66 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-container">
|
<div class="box-container">
|
||||||
<div id="root"></div>
|
<div :id="'root' + props.timestamp"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-controls">
|
<div class="box-controls">
|
||||||
<div>
|
<div class="left-controls">
|
||||||
<n-button quaternary @click="playOrPauseClick">
|
<div>
|
||||||
<template #icon>
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
<n-icon>
|
<template #icon>
|
||||||
<svg
|
<n-icon>
|
||||||
v-if="control_playOrPause"
|
<Pause
|
||||||
version="1.1"
|
v-if="control_playOrPause"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
:style="{
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
fontSize: '20px',
|
||||||
x="0px"
|
color: '#ffffff',
|
||||||
y="0px"
|
}"
|
||||||
viewBox="0 0 512 512"
|
/>
|
||||||
enable-background="new 0 0 512 512"
|
<CaretForward
|
||||||
xml:space="preserve"
|
v-if="!control_playOrPause"
|
||||||
>
|
:style="{
|
||||||
<path d="M96,448h106.7V64H96V448z M309.3,64v384H416V64H309.3z"></path>
|
fontSize: '20px',
|
||||||
</svg>
|
color: '#ffffff',
|
||||||
<svg
|
}"
|
||||||
v-if="!control_playOrPause"
|
/>
|
||||||
version="1.1"
|
</n-icon>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
</template>
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
</n-button>
|
||||||
x="0px"
|
</div>
|
||||||
y="0px"
|
<div>
|
||||||
viewBox="0 0 512 512"
|
<n-button quaternary @click="volumeClick">
|
||||||
enable-background="new 0 0 512 512"
|
<template #icon>
|
||||||
xml:space="preserve"
|
<n-icon>
|
||||||
>
|
<VolumeHigh
|
||||||
<path d="M96,52v408l320-204L96,52z"></path>
|
v-if="!control_volume"
|
||||||
</svg>
|
:style="{
|
||||||
</n-icon>
|
fontSize: '20px',
|
||||||
</template>
|
color: '#ffffff',
|
||||||
</n-button>
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="right-controls">
|
||||||
<n-button quaternary @click="volumeClick">
|
<n-button quaternary @click="fullScreenClick">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon>
|
<n-icon>
|
||||||
<svg
|
<ExpandOutlined
|
||||||
v-if="control_volume"
|
:style="{
|
||||||
version="1.1"
|
fontSize: '20px',
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
color: '#ffffff',
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
}"
|
||||||
x="0px"
|
/>
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
enable-background="new 0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M64,192v128h85.334L256,431.543V80.458L149.334,192H64z M352,256c0-38.399-21.333-72.407-53.333-88.863v176.636
|
|
||||||
C330.667,328.408,352,294.4,352,256z M298.667,64v44.978C360.531,127.632,405.334,186.882,405.334,256
|
|
||||||
c0,69.119-44.803,128.369-106.667,147.022V448C384,428.254,448,349.257,448,256C448,162.744,384,83.746,298.667,64z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
v-if="!control_volume"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
enable-background="new 0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
>
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
d="M405.5,256c0,22.717-4.883,44.362-13.603,63.855l31.88,31.88C439.283,323.33,448,290.653,448,256
|
|
||||||
c0-93.256-64-172.254-149-192v44.978C361,127.632,405.5,186.882,405.5,256z"
|
|
||||||
></path>
|
|
||||||
<polygon points="256,80.458 204.979,132.938 256,183.957 "></polygon>
|
|
||||||
<path
|
|
||||||
d="M420.842,396.885L91.116,67.157l-24,24l90.499,90.413l-8.28,10.43H64v128h85.334L256,431.543V280l94.915,94.686
|
|
||||||
C335.795,387.443,318,397.213,299,403.022V448c31-7.172,58.996-22.163,82.315-42.809l39.61,39.693l24-24.043l-24.002-24.039
|
|
||||||
L420.842,396.885z"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
d="M352.188,256c0-38.399-21.188-72.407-53.188-88.863v59.82l50.801,50.801C351.355,270.739,352.188,263.454,352.188,256z"
|
|
||||||
></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</n-icon>
|
</n-icon>
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
@ -97,18 +71,52 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
let BASE_URL = 'http://111.17.207.220:9001/api';
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
const props = defineProps(['deviceId', 'channelId', 'width', 'height', 'timestamp']);
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
let clPlayer: any = null;
|
let clPlayer: any = null;
|
||||||
|
|
||||||
// 开始播放/暂停播放
|
// 开始播放/暂停播放
|
||||||
const control_playOrPause = ref(true);
|
const control_playOrPause = ref(true);
|
||||||
// 音量
|
// 音量:true为静音
|
||||||
const control_volume = ref(true);
|
const control_volume = ref(true);
|
||||||
// 全屏
|
// 全屏
|
||||||
const control_fullScreen = ref(true);
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
// 获取kitToken
|
// 获取kitToken
|
||||||
function getKitToken(deviceId, channelId) {
|
function getKitToken(deviceId, channelId) {
|
||||||
|
|
@ -126,10 +134,10 @@
|
||||||
// 结束上一个
|
// 结束上一个
|
||||||
closeMonitorVideo();
|
closeMonitorVideo();
|
||||||
|
|
||||||
clPlayer = new window.imouPlayer({
|
clPlayer = new imouPlayer({
|
||||||
id: 'root',
|
id: 'root' + props.timestamp,
|
||||||
width: props.width,
|
width: props.width,
|
||||||
height: props.height,
|
height: props.height - 35,
|
||||||
deviceId: deviceId,
|
deviceId: deviceId,
|
||||||
token: kitToken,
|
token: kitToken,
|
||||||
channelId: channelId,
|
channelId: channelId,
|
||||||
|
|
@ -139,6 +147,7 @@
|
||||||
code: '',
|
code: '',
|
||||||
controls: true,
|
controls: true,
|
||||||
});
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 结束
|
// 结束
|
||||||
|
|
@ -158,6 +167,7 @@
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getKitToken(props.deviceId, props.channelId);
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|
@ -170,22 +180,28 @@
|
||||||
width: v-bind('`${props.width}px`');
|
width: v-bind('`${props.width}px`');
|
||||||
height: v-bind('`${props.height}px`');
|
height: v-bind('`${props.height}px`');
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
.box-container {
|
.box-container {
|
||||||
width: v-bind('`${props.width}px`');
|
width: v-bind('`${props.width}px`');
|
||||||
height: v-bind('`${props.height}px`');
|
height: v-bind('`${props.height-35}px`');
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-controls {
|
.box-controls {
|
||||||
position: absolute;
|
display: grid;
|
||||||
left: 0px;
|
grid-template-columns: auto 1fr;
|
||||||
bottom: 0px;
|
align-items: center;
|
||||||
display: inline-flex;
|
background: #000000;
|
||||||
background: #ffffff00;
|
|
||||||
height: 35px;
|
height: 35px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 100;
|
gap: 10px;
|
||||||
border: 1px solid red;
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<video
|
<div>
|
||||||
:id="'ZhiGan_ModalVideo' + props.timestamp"
|
<video
|
||||||
class="TCPlayer-video-contaiiner"
|
:id="'ZhiGan_ModalVideo' + props.timestamp"
|
||||||
preload="auto"
|
class="TCPlayer-video-container"
|
||||||
crossOrigin="anonymous"
|
preload="auto"
|
||||||
playsinline
|
crossOrigin="anonymous"
|
||||||
autoplay
|
playsinline
|
||||||
:loop="props.videoLoop"
|
autoplay
|
||||||
:muted="props.videoMuted"
|
:loop="props.videoLoop"
|
||||||
:width="props.width"
|
:muted="props.videoMuted"
|
||||||
:height="props.height"
|
:style="{
|
||||||
/>
|
width: props.width + 'px',
|
||||||
|
height: props.height + 'px',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
|
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
|
||||||
|
|
||||||
|
|
@ -29,14 +34,14 @@
|
||||||
let player: any = null;
|
let player: any = null;
|
||||||
|
|
||||||
function handlerPlayVideo() {
|
function handlerPlayVideo() {
|
||||||
setTimeout(function () {
|
nextTick(() => {
|
||||||
if (player) {
|
if (player) {
|
||||||
player.src(props.serialNumberValue);
|
player.src(props.serialNumberValue);
|
||||||
} else {
|
} else {
|
||||||
player = TCPlayer('ZhiGan_ModalVideo' + props.timestamp, {});
|
player = TCPlayer('ZhiGan_ModalVideo' + props.timestamp, {});
|
||||||
player.src(props.serialNumberValue);
|
player.src(props.serialNumberValue);
|
||||||
}
|
}
|
||||||
}, 1000);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePlayerVideo() {
|
function closePlayerVideo() {
|
||||||
|
|
@ -56,6 +61,7 @@
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handlerPlayVideo();
|
handlerPlayVideo();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
closePlayerVideo();
|
closePlayerVideo();
|
||||||
});
|
});
|
||||||
|
|
@ -65,6 +71,7 @@
|
||||||
closePlayerVideo,
|
closePlayerVideo,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
video {
|
video {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -68,10 +68,10 @@ export const option = {
|
||||||
videoWidth: 956,
|
videoWidth: 956,
|
||||||
videoHeight: 688,
|
videoHeight: 688,
|
||||||
// 关闭按钮
|
// 关闭按钮
|
||||||
closeVideoIconColor: '#027734',
|
closeVideoIconColor: '#ffffff',
|
||||||
closeVideoIconWidthAndHeight: 34,
|
closeVideoIconWidthAndHeight: 25,
|
||||||
// 标题
|
// 标题
|
||||||
videoTitleFontSize: 16,
|
videoTitleFontSize: 20,
|
||||||
videoTitleFontColor: '#ffffff',
|
videoTitleFontColor: '#ffffff',
|
||||||
|
|
||||||
videoloop: false, // 视频-循环播放
|
videoloop: false, // 视频-循环播放
|
||||||
|
|
|
||||||
|
|
@ -4,49 +4,41 @@
|
||||||
"label": "费县林业防火监控列表",
|
"label": "费县林业防火监控列表",
|
||||||
"value": [
|
"value": [
|
||||||
{
|
{
|
||||||
"id": 418015298064389,
|
|
||||||
"title": "XZD148青山裕南山",
|
"title": "XZD148青山裕南山",
|
||||||
"videourl": "13b23c9b878143bc99269898964af54f",
|
"videourl": "13b23c9b878143bc99269898964af54f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349661701,
|
|
||||||
"title": "XZD153狼窝沟西南",
|
"title": "XZD153狼窝沟西南",
|
||||||
"videourl": "74b95e6575d741489b9a9061bb646467",
|
"videourl": "74b95e6575d741489b9a9061bb646467",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015349899269,
|
|
||||||
"title": "XZD152青山裕水库东",
|
"title": "XZD152青山裕水库东",
|
||||||
"videourl": "ecdb49050c57452dbae7ec6f03e82667",
|
"videourl": "ecdb49050c57452dbae7ec6f03e82667",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015350452229,
|
|
||||||
"title": "XZD147大古台南山",
|
"title": "XZD147大古台南山",
|
||||||
"videourl": "edd84ccac34441c48c6a7bf030f9c13f",
|
"videourl": "edd84ccac34441c48c6a7bf030f9c13f",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351681029,
|
|
||||||
"title": "XZD151青山裕水库西",
|
"title": "XZD151青山裕水库西",
|
||||||
"videourl": "c10f9faea87d4f659e2bc01de24e29a9",
|
"videourl": "c10f9faea87d4f659e2bc01de24e29a9",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351836677,
|
|
||||||
"title": "XZD149青山裕北山",
|
"title": "XZD149青山裕北山",
|
||||||
"videourl": "909e98d192f649fea4c5269f5f7832e1",
|
"videourl": "909e98d192f649fea4c5269f5f7832e1",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 418015351025669,
|
|
||||||
"title": "XZD150青山裕山里人家西北",
|
"title": "XZD150青山裕山里人家西北",
|
||||||
"videourl": "b56f09f8c64249379e42481c7b173dce",
|
"videourl": "b56f09f8c64249379e42481c7b173dce",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 490483936976901,
|
|
||||||
"title": "XZD155突围路广场",
|
"title": "XZD155突围路广场",
|
||||||
"videourl": "a8010ac49baa4b81a569ba24dc95a4e7",
|
"videourl": "a8010ac49baa4b81a569ba24dc95a4e7",
|
||||||
"manufacturer": "海康"
|
"manufacturer": "海康"
|
||||||
|
|
@ -54,42 +46,47 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县东蒙镇沂蒙抽水蓄能业营地",
|
"title":"费县东蒙镇沂蒙抽水蓄能业营地",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县薛庄镇火山后村南斜坡后村",
|
"title":"费县薛庄镇火山后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县冯庄镇陈家鱼后村南斜坡后村",
|
"title":"费县冯庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
|
||||||
{
|
|
||||||
"title":"费县东蒙镇天蒙景区二村东边南斜坡后村",
|
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
|
||||||
"manufacturer": ""
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县冻蒙镇沂蒙抽水蓄能业营地",
|
"title":"费县冻蒙镇沂蒙抽水蓄能业营地",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"费县薛庄镇火山后村南斜坡后村",
|
"title": "店子分区",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "8H03AA1PAGDC8C3",
|
||||||
"manufacturer": ""
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "白马关通天沟",
|
||||||
|
"videourl": "8H03AA1PAG97234",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "后白崖",
|
||||||
|
"videourl": "8H03AA1PAGF203B",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
v-for="(videoItem, videoIndex) in option.videoList"
|
v-for="(videoItem, videoIndex) in option.videoList"
|
||||||
:key="videoIndex"
|
:key="videoIndex"
|
||||||
>
|
>
|
||||||
<div class="rightVideoItemTitle" v-if="isEdit || videoItem.title">
|
<div class="rightVideoItemTitle" v-if="isEdit">
|
||||||
<span
|
<span
|
||||||
:style="{
|
:style="{
|
||||||
color: option.dataStyle.videoTitleFontColor,
|
color: option.dataStyle.videoTitleFontColor,
|
||||||
|
|
@ -84,15 +84,18 @@
|
||||||
{{ videoItem.title ? videoItem.title : '视频标题' }}
|
{{ videoItem.title ? videoItem.title : '视频标题' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="rightVideoItemCloseButton" v-if="isEdit || videoItem.videourl">
|
<div class="rightVideoItemCloseButton" v-if="isEdit">
|
||||||
<CloseVideoIcon :dataStyle="option.dataStyle" @click="closeThisVideo(videoIndex)" />
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: option.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: option.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div :class="changeThisNum == videoIndex ? 'rightVideoItemDiv2' : 'rightVideoItemDiv'">
|
||||||
:class="changeThisNum == videoIndex ? 'rightVideoItemDiv2' : 'rightVideoItemDiv'"
|
|
||||||
@click="changeThisVideo(videoIndex)"
|
|
||||||
>
|
|
||||||
<!-- 无视频url的情况 -->
|
|
||||||
<img
|
<img
|
||||||
v-if="isEdit || !videoItem.videourl"
|
v-if="isEdit || !videoItem.videourl"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
|
|
@ -100,24 +103,42 @@
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
preview-disabled
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
:index="videoIndex"
|
:index="videoIndex"
|
||||||
:serialNumberValue="videoItem.videourl"
|
:serialNumberValue="videoItem.videourl"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
:height="videoHeightNoPadding"
|
:height="videoHeightNoPadding"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:dataStyle="option.dataStyle"
|
||||||
|
@changeThisVideo="changeThisVideo"
|
||||||
|
@closeThisVideo="closeThisVideo"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorLC
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:title="videoItem.title"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="videoIndex"
|
||||||
|
:width="videoWidthNoPadding"
|
||||||
|
:height="videoHeightNoPadding"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
:dataStyle="option.dataStyle"
|
||||||
|
@changeThisVideo="changeThisVideo"
|
||||||
|
@closeThisVideo="closeThisVideo"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
|
:title="videoItem.title"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="videoIndex"
|
:index="videoIndex"
|
||||||
:width="videoWidthNoPadding"
|
:width="videoWidthNoPadding"
|
||||||
:height="videoHeightNoPadding"
|
:height="videoHeightNoPadding"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
:videoLoop="option.dataStyle.videoLoop"
|
:dataStyle="option.dataStyle"
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
@changeThisVideo="changeThisVideo"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
@closeThisVideo="closeThisVideo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -146,15 +167,15 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { EventBus } from '@/utils/eventBus';
|
import { EventBus } from '@/utils/eventBus';
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
|
import { Close } from '@vicons/ionicons5';
|
||||||
import {
|
import {
|
||||||
CloseButton,
|
CloseButton,
|
||||||
TypeButton,
|
TypeButton,
|
||||||
LeftTitleIcon1,
|
LeftTitleIcon1,
|
||||||
LeftTitleIcon2,
|
LeftTitleIcon2,
|
||||||
ListVideoNameIcon,
|
ListVideoNameIcon,
|
||||||
CloseVideoIcon,
|
|
||||||
} from './svg/index';
|
} from './svg/index';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
|
||||||
|
|
@ -639,8 +660,8 @@
|
||||||
.rightVideoItemDiv2 {
|
.rightVideoItemDiv2 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: v-bind('`${17 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
|
padding: v-bind('`${14 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`');
|
||||||
border: v-bind('`${3 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`') solid #0fab3f;
|
border: v-bind('`${6 / Math.sqrt(parseInt(option.dataStyle.nowType))}px`') solid #0fab3f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
import { JSEncrypt } from 'jsencrypt';
|
import { JSEncrypt } from 'jsencrypt';
|
||||||
|
|
||||||
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
//声明公用变量
|
//声明公用变量
|
||||||
let initCount = 0;
|
let initCount = 0;
|
||||||
|
|
@ -110,7 +111,7 @@
|
||||||
let encryptedFields = 'secret'; //加密字段,默认加密领域为secret
|
let encryptedFields = 'secret'; //加密字段,默认加密领域为secret
|
||||||
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
|
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
|
||||||
let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
|
let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
|
||||||
let buttonIDs = '0,16'; //自定义工具条按钮
|
let buttonIDs = '0'; //自定义工具条按钮
|
||||||
|
|
||||||
oWebControl
|
oWebControl
|
||||||
.JS_RequestInterface({
|
.JS_RequestInterface({
|
||||||
|
|
@ -134,6 +135,26 @@
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 重定大小
|
// 重定大小
|
||||||
reSizeVideo();
|
reSizeVideo();
|
||||||
|
// 单击-选择+反选择
|
||||||
|
oWebControl.JS_SetWindowControlCallback({
|
||||||
|
cbIntegrationCallBack: function (oData) {
|
||||||
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
if (oData.responseMsg.type == '1' && oData.responseMsg.msg.result == '256') {
|
||||||
|
// 选择这个视频
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
// // oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
// if (oData.responseMsg.type == '1' && oData.responseMsg.msg.result == '512') {
|
||||||
|
// // 按下关闭按钮
|
||||||
|
// emit('closeThisVideo', props.index);
|
||||||
|
// }
|
||||||
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
|
if (oData.responseMsg.type == '2' && oData.responseMsg.msg.result == '816') {
|
||||||
|
// 按下全部关闭按钮
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 开始预览多个视频
|
// 开始预览多个视频
|
||||||
|
|
@ -227,10 +248,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_SheXiangTouModal');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_SheXiangTouModal');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
@ -0,0 +1,284 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="box-title">
|
||||||
|
<div class="left-controls">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
fontSize: props.dataStyle.videoTitleFontSize + 'px',
|
||||||
|
color: props.dataStyle.videoTitleFontColor,
|
||||||
|
marginLeft: '10px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ props.title }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="closeVideo">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: props.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 视频 -->
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp" @click="clickThisVideo" />
|
||||||
|
</div>
|
||||||
|
<!-- 控制栏 -->
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Close, Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'title',
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'dataStyle',
|
||||||
|
]);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 点击视频内容
|
||||||
|
function clickThisVideo() {
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭此视频;
|
||||||
|
function closeVideo() {
|
||||||
|
closeMonitorVideo();
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
let kitToken = null;
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测视频id
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// 检测宽度
|
||||||
|
watch(
|
||||||
|
() => props.width,
|
||||||
|
() => {
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
deviceId: props.deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: props.channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.dataStyle.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-title {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-70}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="box-title">
|
||||||
|
<div class="left-title">
|
||||||
|
<span
|
||||||
|
:style="{
|
||||||
|
fontSize: props.dataStyle.videoTitleFontSize + 'px',
|
||||||
|
color: props.dataStyle.videoTitleFontColor,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ props.title }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="right-title">
|
||||||
|
<n-button quaternary @click="closeVideo">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Close
|
||||||
|
:style="{
|
||||||
|
width: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
height: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
fontSize: props.dataStyle.closeVideoIconWidthAndHeight + 'px',
|
||||||
|
color: props.dataStyle.closeVideoIconColor,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 视频 -->
|
||||||
|
<video
|
||||||
|
:id="'ZhiGan_SheXiangTouModal' + props.index + props.timestamp"
|
||||||
|
class="TCPlayer-video-contaiiner"
|
||||||
|
preload="auto"
|
||||||
|
crossOrigin="anonymous"
|
||||||
|
playsinline
|
||||||
|
autoplay
|
||||||
|
:loop="props.dataStyle.videoLoop"
|
||||||
|
:muted="props.dataStyle.videoMuted"
|
||||||
|
@click="clickThisVideo"
|
||||||
|
/>
|
||||||
|
<!-- 控制栏 -->
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { nextTick, onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Close, Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'title',
|
||||||
|
'videourl',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'dataStyle',
|
||||||
|
]);
|
||||||
|
const emit = defineEmits(['changeThisVideo', 'closeThisVideo']);
|
||||||
|
|
||||||
|
// 关闭此视频;
|
||||||
|
function closeVideo() {
|
||||||
|
closePlayerVideo();
|
||||||
|
emit('closeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
txPlayer.play();
|
||||||
|
} else {
|
||||||
|
txPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
txPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
txPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
txPlayer.requestFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.videourl,
|
||||||
|
() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.width,
|
||||||
|
() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 视频控件初始化
|
||||||
|
let txPlayer: any = null;
|
||||||
|
function handlerPlayVideo() {
|
||||||
|
nextTick(function () {
|
||||||
|
if (txPlayer) {
|
||||||
|
txPlayer.src(props.videourl);
|
||||||
|
txPlayer.width(props.width);
|
||||||
|
txPlayer.height(props.height - 70);
|
||||||
|
} else {
|
||||||
|
txPlayer = TCPlayer('ZhiGan_SheXiangTouModal' + props.index + props.timestamp, {
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 70,
|
||||||
|
controls: false,
|
||||||
|
});
|
||||||
|
txPlayer.src(props.videourl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭此视频
|
||||||
|
function closePlayerVideo() {
|
||||||
|
if (txPlayer) {
|
||||||
|
txPlayer.dispose();
|
||||||
|
txPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击视频内容
|
||||||
|
function clickThisVideo() {
|
||||||
|
emit('changeThisVideo', props.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
handlerPlayVideo();
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closePlayerVideo();
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
handlerPlayVideo,
|
||||||
|
closePlayerVideo,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.box-title {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-title {
|
||||||
|
position: absolute;
|
||||||
|
top: 0%;
|
||||||
|
left: 0%;
|
||||||
|
z-index: 100;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.right-title {
|
||||||
|
position: absolute;
|
||||||
|
top: -10%;
|
||||||
|
right: 0%;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
video {
|
||||||
|
display: block;
|
||||||
|
object-fit: v-bind('props.dataStyle.videoFit');
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .vjs-live-display {
|
||||||
|
width: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .vjs-button {
|
||||||
|
width: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<video
|
|
||||||
:id="'ZhiGan_SheXiangTouModal' + props.index + props.timestamp"
|
|
||||||
class="TCPlayer-video-contaiiner"
|
|
||||||
preload="auto"
|
|
||||||
crossOrigin="anonymous"
|
|
||||||
playsinline
|
|
||||||
autoplay
|
|
||||||
:loop="props.videoLoop"
|
|
||||||
:muted="props.videoMuted"
|
|
||||||
:style="{
|
|
||||||
width: props.width + 'px',
|
|
||||||
height: props.height + 'px',
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onMounted, onUnmounted, watch } from 'vue';
|
|
||||||
|
|
||||||
const props = defineProps([
|
|
||||||
'videourl',
|
|
||||||
'index',
|
|
||||||
'width',
|
|
||||||
'height',
|
|
||||||
'timestamp',
|
|
||||||
'videoLoop',
|
|
||||||
'videoMuted',
|
|
||||||
'videoFit',
|
|
||||||
]);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.videourl,
|
|
||||||
() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
watch(
|
|
||||||
() => props.width,
|
|
||||||
() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 视频控件初始化
|
|
||||||
let player: any = null;
|
|
||||||
|
|
||||||
function handlerPlayVideo() {
|
|
||||||
nextTick(function () {
|
|
||||||
if (player) {
|
|
||||||
player.src(props.videourl);
|
|
||||||
} else {
|
|
||||||
player = TCPlayer('ZhiGan_SheXiangTouModal' + props.index + props.timestamp, {});
|
|
||||||
player.src(props.videourl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePlayerVideo() {
|
|
||||||
if (player) {
|
|
||||||
player.dispose();
|
|
||||||
player = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
handlerPlayVideo();
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
closePlayerVideo();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
handlerPlayVideo,
|
|
||||||
closePlayerVideo,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
video {
|
|
||||||
display: block;
|
|
||||||
object-fit: v-bind('props.videoFit');
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .vjs-live-display {
|
|
||||||
width: 40px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .vjs-button {
|
|
||||||
width: 20px !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -23,32 +23,47 @@
|
||||||
{
|
{
|
||||||
"title":"DJA-72无人机监控画面",
|
"title":"DJA-72无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJ-057无人机监控画面",
|
"title":"DJ-057无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-20无人机监控画面",
|
"title":"DJA-20无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-035无人机监控画面",
|
"title":"DJA-035无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJA-11无人机监控画面",
|
"title":"DJA-11无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"DJ-021无人机监控画面",
|
"title":"DJ-021无人机监控画面",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "白马关通天沟",
|
||||||
|
"videourl": "8H03AA1PAG97234",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "天宝山林场",
|
||||||
|
"videourl": "8L0995DPAG11E58",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
<MonitorHK
|
||||||
v-if="!isEdit && item.manufacturer == '海康'"
|
v-if="!isEdit && item.manufacturer == '海康'"
|
||||||
:index="index"
|
:index="index"
|
||||||
:serialNumberValue="item.videourl"
|
:serialNumberValue="item.videourl"
|
||||||
|
|
@ -65,8 +65,18 @@
|
||||||
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
:timestamp="option.dataStyle.timestamp"
|
:timestamp="option.dataStyle.timestamp"
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorLC
|
||||||
v-if="!isEdit && !item.manufacturer"
|
v-if="!isEdit && item.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
:height="`${option.dataStyle.videoheight - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.manufacturer == '腾讯'"
|
||||||
:videourl="item.videourl"
|
:videourl="item.videourl"
|
||||||
:index="index"
|
:index="index"
|
||||||
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
:width="`${option.dataStyle.videowidth - 2 * option.dataStyle.borderWidth - 2 * option.dataStyle.padding}`"
|
||||||
|
|
@ -109,7 +119,7 @@
|
||||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, watch, defineProps, defineExpose, ref, computed } from 'vue';
|
import { onMounted, onUnmounted, watch, nextTick, ref, computed } from 'vue';
|
||||||
import { JSEncrypt } from 'jsencrypt';
|
import { JSEncrypt } from 'jsencrypt';
|
||||||
|
|
||||||
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
const props = defineProps(['serialNumberValue', 'index', 'width', 'height', 'timestamp']);
|
||||||
|
|
@ -132,27 +132,12 @@
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.then(function (oData) {
|
.then(function (oData) {
|
||||||
// 实际宽高
|
// 重定大小
|
||||||
let width = props.width;
|
reSizeVideo();
|
||||||
let height = props.height;
|
// 双击-全屏
|
||||||
const divElement = document.getElementById('camera-box-' + props.index);
|
|
||||||
if (divElement) {
|
|
||||||
const rect = divElement.getBoundingClientRect();
|
|
||||||
const rectWidth = rect.width;
|
|
||||||
const rectHeight = rect.height;
|
|
||||||
if (rectWidth < width) {
|
|
||||||
width = rectWidth;
|
|
||||||
}
|
|
||||||
if (rectHeight < height) {
|
|
||||||
height = rectHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
|
||||||
|
|
||||||
oWebControl.JS_SetWindowControlCallback({
|
oWebControl.JS_SetWindowControlCallback({
|
||||||
cbIntegrationCallBack: function (oData) {
|
cbIntegrationCallBack: function (oData) {
|
||||||
// oData 是封装的视频 web 插件回调消息的消息体
|
// oData 是封装的视频 web 插件回调消息的消息体
|
||||||
// 双击-全屏
|
|
||||||
if (oData.responseMsg.type == '7') {
|
if (oData.responseMsg.type == '7') {
|
||||||
setFullScreen();
|
setFullScreen();
|
||||||
}
|
}
|
||||||
|
|
@ -210,6 +195,27 @@
|
||||||
return encrypt.encrypt(value);
|
return encrypt.encrypt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重定大小
|
||||||
|
function reSizeVideo() {
|
||||||
|
if (oWebControl != null) {
|
||||||
|
// 实际宽高
|
||||||
|
let width = props.width;
|
||||||
|
let height = props.height;
|
||||||
|
const divElement = document.getElementById('camera-box-' + props.index);
|
||||||
|
if (divElement) {
|
||||||
|
const rect = divElement.getBoundingClientRect();
|
||||||
|
const rectWidth = rect.width;
|
||||||
|
const rectHeight = rect.height;
|
||||||
|
if (rectWidth < width) {
|
||||||
|
width = rectWidth;
|
||||||
|
}
|
||||||
|
if (rectHeight < height) {
|
||||||
|
height = rectHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oWebControl.JS_Resize(width, height); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
|
||||||
|
}
|
||||||
|
}
|
||||||
// 全屏
|
// 全屏
|
||||||
function setFullScreen() {
|
function setFullScreen() {
|
||||||
oWebControl.JS_RequestInterface({
|
oWebControl.JS_RequestInterface({
|
||||||
|
|
@ -217,16 +223,42 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.serialNumberValue,
|
||||||
|
() => {
|
||||||
|
// 初始化播放内容
|
||||||
|
init();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// 推送消息
|
// 推送消息
|
||||||
function cbIntegrationCallBack(oData) {
|
function cbIntegrationCallBack(oData) {
|
||||||
// showCBInfo(JSON.stringify(oData.responseMsg));
|
// showCBInfo(JSON.stringify(oData.responseMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 启动视频窗口
|
||||||
initPlugin();
|
initPlugin();
|
||||||
|
// 添加监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_WuRenJiShiShiHuaMian');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 销毁视频窗口
|
||||||
closeHkVideo();
|
closeHkVideo();
|
||||||
|
// 移除监听滚动事件
|
||||||
|
const elements = document.querySelectorAll('.ZhiGan_WuRenJiShiShiHuaMian');
|
||||||
|
if (elements.length > 0) {
|
||||||
|
// 遍历每个元素并绑定 scroll 事件
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.removeEventListener('scroll', reSizeVideo);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 35,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-35}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 35px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -15,7 +15,12 @@
|
||||||
{
|
{
|
||||||
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
"title":"费县马庄镇陈家鱼后村南斜坡后村",
|
||||||
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
"videourl": "http://111.36.45.20:18000/flv/hls/H-dcb1ea7388588111.flv",
|
||||||
"manufacturer": ""
|
"manufacturer": "腾讯"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title":"可落",
|
||||||
|
"videourl": "8H03AA1PAG8D9BF",
|
||||||
|
"manufacturer": "乐橙"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -126,10 +126,27 @@
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && videoItem.videourl && !videoItem.manufacturer"
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="videoItem.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '乐橙'"
|
||||||
|
:deviceId="videoItem.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '腾讯'"
|
||||||
:videourl="videoItem.videourl"
|
:videourl="videoItem.videourl"
|
||||||
:index="index + '-' + videoIndex"
|
:index="index + '-' + videoIndex"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -139,14 +156,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && videoItem.videourl && videoItem.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="videoItem.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 单个 -->
|
<!-- 单个 -->
|
||||||
|
|
@ -161,10 +170,27 @@
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
src="@/assets/images/chart/zhichu/component/SheXiangTouModal_Image.png"
|
||||||
preview-disabled
|
|
||||||
/>
|
/>
|
||||||
<PlayVideo
|
<MonitorHK
|
||||||
v-if="!isEdit && item.videos.videourl && !item.videos.manufacturer"
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
||||||
|
:index="index + '-' + videoIndex"
|
||||||
|
:serialNumberValue="item.videos.videourl"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
/>
|
||||||
|
<MonitorLC
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '乐橙'"
|
||||||
|
:deviceId="item.videos.videourl"
|
||||||
|
:channelId="0"
|
||||||
|
:index="index"
|
||||||
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
:timestamp="option.dataStyle.timestamp"
|
||||||
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
|
/>
|
||||||
|
<MonitorTX
|
||||||
|
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '腾讯'"
|
||||||
:videourl="item.videos.videourl"
|
:videourl="item.videos.videourl"
|
||||||
:index="index + '-0'"
|
:index="index + '-0'"
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
||||||
|
|
@ -174,14 +200,6 @@
|
||||||
:videoMuted="option.dataStyle.videoMuted"
|
:videoMuted="option.dataStyle.videoMuted"
|
||||||
:videoFit="option.dataStyle.videoFit"
|
:videoFit="option.dataStyle.videoFit"
|
||||||
/>
|
/>
|
||||||
<MulHKmonitor
|
|
||||||
v-if="!isEdit && item.videos.videourl && item.videos.manufacturer == '海康'"
|
|
||||||
:index="index + '-' + videoIndex"
|
|
||||||
:serialNumberValue="item.videos.videourl"
|
|
||||||
:width="`${option.dataStyle.videoWidth - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:height="`${option.dataStyle.videoHeight - 2 * option.dataStyle.videoBorderWidth - 2 * option.dataStyle.videoPadding}`"
|
|
||||||
:timestamp="option.dataStyle.timestamp"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -200,7 +218,7 @@
|
||||||
import { replaceSqlParams } from '@/utils/sqlHandler';
|
import { replaceSqlParams } from '@/utils/sqlHandler';
|
||||||
import Title from './svg/title.vue';
|
import Title from './svg/title.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { MulHKmonitor, PlayVideo } from './video/index';
|
import { MonitorHK, MonitorLC, MonitorTX } from './video/index';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
chartConfig: {
|
chartConfig: {
|
||||||
|
|
@ -313,7 +331,7 @@
|
||||||
|
|
||||||
.timeLineVideoDivTitle {
|
.timeLineVideoDivTitle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 100;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
left: 5px;
|
left: 5px;
|
||||||
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
font-size: v-bind('`${option.dataStyle.videoTitleFontSize}px`');
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import MulHKmonitor from './mulHKmonitor.vue';
|
import MonitorHK from './monitorHK.vue';
|
||||||
import PlayVideo from './playVideo.vue';
|
import MonitorLC from './monitorLC.vue';
|
||||||
|
import MonitorTX from './monitorTX.vue';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
MulHKmonitor,
|
MonitorHK,
|
||||||
PlayVideo,
|
MonitorLC,
|
||||||
|
MonitorTX,
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
<template>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-container">
|
||||||
|
<div :id="'root' + props.index + props.timestamp"></div>
|
||||||
|
</div>
|
||||||
|
<div class="box-controls">
|
||||||
|
<div class="left-controls">
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="playOrPauseClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Pause
|
||||||
|
v-if="control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<CaretForward
|
||||||
|
v-if="!control_playOrPause"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<n-button quaternary @click="volumeClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<VolumeHigh
|
||||||
|
v-if="!control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
<VolumeMute
|
||||||
|
v-if="control_volume"
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right-controls">
|
||||||
|
<n-button quaternary @click="fullScreenClick">
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<ExpandOutlined
|
||||||
|
:style="{
|
||||||
|
fontSize: '20px',
|
||||||
|
color: '#ffffff',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, watch, ref } from 'vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ExpandOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Pause, CaretForward, VolumeHigh, VolumeMute } from '@vicons/ionicons5';
|
||||||
|
|
||||||
|
let BASE_URL = 'http://111.17.207.220:9001/api';
|
||||||
|
|
||||||
|
const props = defineProps([
|
||||||
|
'deviceId',
|
||||||
|
'channelId',
|
||||||
|
'index',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'timestamp',
|
||||||
|
'videoMuted',
|
||||||
|
]);
|
||||||
|
let clPlayer: any = null;
|
||||||
|
|
||||||
|
// 开始播放/暂停播放
|
||||||
|
const control_playOrPause = ref(true);
|
||||||
|
// 音量:true为静音
|
||||||
|
const control_volume = ref(true);
|
||||||
|
// 全屏
|
||||||
|
const control_fullScreen = ref(false);
|
||||||
|
|
||||||
|
// 开始播放/暂停播放方法
|
||||||
|
function playOrPauseClick() {
|
||||||
|
control_playOrPause.value = !control_playOrPause.value;
|
||||||
|
if (control_playOrPause.value) {
|
||||||
|
clPlayer.play();
|
||||||
|
} else {
|
||||||
|
clPlayer.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 音量
|
||||||
|
function volumeClick() {
|
||||||
|
control_volume.value = !control_volume.value;
|
||||||
|
if (control_volume.value) {
|
||||||
|
clPlayer.volume(0);
|
||||||
|
} else {
|
||||||
|
clPlayer.volume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
function fullScreenClick() {
|
||||||
|
clPlayer.fullScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取kitToken
|
||||||
|
function getKitToken(deviceId, channelId) {
|
||||||
|
axios({
|
||||||
|
method: 'post',
|
||||||
|
url: BASE_URL + '/Camera/getKitToken?deviceId=' + deviceId + '&channelId=0' + '&type=0',
|
||||||
|
}).then((res) => {
|
||||||
|
let kitToken = res.data.result.data.kitToken;
|
||||||
|
loadMonitorVideo(deviceId, kitToken, channelId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
function loadMonitorVideo(deviceId, kitToken, channelId) {
|
||||||
|
// 结束上一个
|
||||||
|
closeMonitorVideo();
|
||||||
|
|
||||||
|
clPlayer = new imouPlayer({
|
||||||
|
id: 'root' + props.index + props.timestamp,
|
||||||
|
width: props.width,
|
||||||
|
height: props.height - 25,
|
||||||
|
deviceId: deviceId,
|
||||||
|
token: kitToken,
|
||||||
|
channelId: channelId,
|
||||||
|
type: 1,
|
||||||
|
streamId: 0,
|
||||||
|
recordType: 'cloud',
|
||||||
|
code: '',
|
||||||
|
controls: true,
|
||||||
|
});
|
||||||
|
clPlayer.volume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束
|
||||||
|
function closeMonitorVideo() {
|
||||||
|
if (clPlayer != null) {
|
||||||
|
clPlayer.destroy();
|
||||||
|
clPlayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.deviceId,
|
||||||
|
() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getKitToken(props.deviceId, props.channelId);
|
||||||
|
control_volume.value = props.videoMuted;
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
closeMonitorVideo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.box {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height}px`');
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
.box-container {
|
||||||
|
width: v-bind('`${props.width}px`');
|
||||||
|
height: v-bind('`${props.height-25}px`');
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
align-items: center;
|
||||||
|
background: #000000;
|
||||||
|
height: 25px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-self: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-controls {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<video
|
<video
|
||||||
:id="'ZhiGan_ModalTimeLine' + props.index + props.timestamp"
|
:id="'HuoQingDetailTimeLine' + props.index + props.timestamp"
|
||||||
class="TCPlayer-video-contaiiner"
|
class="TCPlayer-video-contaiiner"
|
||||||
preload="auto"
|
preload="auto"
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
if (player) {
|
if (player) {
|
||||||
player.src(props.videourl);
|
player.src(props.videourl);
|
||||||
} else {
|
} else {
|
||||||
player = TCPlayer('ZhiGan_ModalTimeLine' + props.index + props.timestamp, {});
|
player = TCPlayer('HuoQingDetailTimeLine' + props.index + props.timestamp, {});
|
||||||
player.src(props.videourl);
|
player.src(props.videourl);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Loading…
Reference in New Issue