|
@@ -1,18 +1,655 @@
|
|
|
<template>
|
|
|
<div class="container-ln">
|
|
|
<customHeader>潞宁新增</customHeader>
|
|
|
+ <div class="video-ln">
|
|
|
+ <div v-for="(item, index) in addrList" :key="index" class="video-module">
|
|
|
+ <div class="player-name">{{ item.name }}</div>
|
|
|
+ <div style="padding-top:3px">
|
|
|
+ <template v-if="item.addr.startsWith('rtsp://')">
|
|
|
+ <video :id="`video${index}`" muted autoplay></video>
|
|
|
+ <div class="click-box" @dblclick="goFullScreen(`video${index}`)"></div>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div :id="'player' + index"></div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="content-ln">
|
|
|
+ <a-tabs class="tabs-box" type="card" v-model:activeKey="activeKey" @change="tabChange" id="tabsBox">
|
|
|
+ <a-tab-pane key="1" tab="安全监控">
|
|
|
+ <template v-if="deviceType == 'fan' && activeKey == '1'">
|
|
|
+ <GroupMonitorTable :dataSource="dataSource" :columnsType="`${deviceType}_monitor`" />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="activeKey == '1' && deviceType">
|
|
|
+ <template v-if="hasPermission('btn:noGb')">
|
|
|
+ <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`"
|
|
|
+ :dataSource="dataSource" design-scope="device_monitor" :isShowPagination="false"
|
|
|
+ :isShowActionColumn="isHaveAction.includes(deviceType.split('_')[0]) ? false : true"
|
|
|
+ :is-show-select="false" title="设备监测" :scroll="{ y: 360 }" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`"
|
|
|
+ :dataSource="dataSource" design-scope="device_monitor" :isShowPagination="false"
|
|
|
+ :isShowActionColumn="isHaveAction.includes(deviceType.split('_')[0]) ? false : true"
|
|
|
+ :is-show-select="false" title="设备监测"
|
|
|
+ :form-config="deviceType == 'safetymonitor' && sysOrgCode != 'zjtzqctmk' ? formConfig : undefined"
|
|
|
+ :scroll="{ y: 650 }">
|
|
|
+ <template #filterCell="{ column, record }">
|
|
|
+ <template v-if="deviceType.startsWith('gate')">
|
|
|
+ <template
|
|
|
+ v-if="record.frontGateOpenCtrl == 1 || record.frontGateOpenCtrl === true">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
|
|
|
+ color="red">正在打开</a-tag>
|
|
|
+ <a-tag v-else-if="column.dataIndex === 'frontGateOpen'"
|
|
|
+ color="processing">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-else-if="record.frontGateOpenCtrl == 0 || record.frontGateOpenCtrl === false">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
|
|
|
+ color="red">正在关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 1"
|
|
|
+ color="default">关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == 0"
|
|
|
+ color="default">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-if="record.rearGateOpenCtrl == 1 || record.rearGateOpenCtrl === true">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
|
|
|
+ color="red">正在打开</a-tag>
|
|
|
+ <a-tag v-else-if="column.dataIndex === 'rearGateOpen'"
|
|
|
+ color="processing">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-else-if="record.rearGateOpenCtrl == 0 || record.rearGateOpenCtrl === false">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
|
|
|
+ color="red">正在关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 1"
|
|
|
+ color="default">关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == 0"
|
|
|
+ color="default">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-if="deviceType.startsWith('windrect')">
|
|
|
+ <a-tag v-if="column.dataIndex === 'sign'"
|
|
|
+ :color="record.sign == '0' ? '#95CF65' : record.sign == 1 ? '#4590EA' : '#9876AA'">
|
|
|
+ {{ record.sign == '0' ? '高位' : record.sign == 1 ? '中位' : '低位' }}</a-tag>
|
|
|
+ <template
|
|
|
+ v-if="record && column && column.dataIndex === 'isRun' && record.isRun">
|
|
|
+ <a-tag v-if="record.isRun == -2 || record.isRun == -1"
|
|
|
+ :color="record.isRun == -2 ? '#95CF65' : '#ED5700'">{{
|
|
|
+ record.isRun == -2 ? '空闲' : '等待'
|
|
|
+ }}</a-tag>
|
|
|
+ <a-tag v-else-if="record.isRun == 100" color="#4693FF">完成</a-tag>
|
|
|
+ <Progress v-else :percent="Number(record.isRun)" size="small"
|
|
|
+ status="active" />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-if="deviceType.startsWith('safetymonitor')">
|
|
|
+ <div v-if="!record.devicename && column.dataIndex === 'devicename'">-</div>
|
|
|
+ <div v-if="!record.V && column.dataIndex === 'V'">-</div>
|
|
|
+ <div v-if="!record.PointUnit && column.dataIndex === 'PointUnit'">-</div>
|
|
|
+ <div v-if="!record.highRange && column.dataIndex === 'highRange'">-</div>
|
|
|
+ <div v-if="!record.lowRange && column.dataIndex === 'lowRange'">-</div>
|
|
|
+ <div v-if="!record.dataTypeName && column.dataIndex === 'dataTypeName'">-</div>
|
|
|
+ </template>
|
|
|
+ <a-tag v-if="column.dataIndex === 'warnFlag'"
|
|
|
+ :color="record.warnFlag == '0' ? 'green' : record.warnFlag == 1 ? '#FF5812' : 'gray'">
|
|
|
+ {{ record.warnFlag == '0' ? '正常' : record.warnFlag == 1 ? '报警' : record.warnFlag
|
|
|
+ == 2 ? '断开' : '未监测'
|
|
|
+ }}</a-tag>
|
|
|
+ <a-tag v-if="column.dataIndex === 'netStatus'"
|
|
|
+ :color="record.netStatus == '0' ? '#f00' : 'green'">{{
|
|
|
+ record.netStatus == '0' ? '断开' : '连接'
|
|
|
+ }}</a-tag>
|
|
|
+ </template>
|
|
|
+ </MonitorTable>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </a-tab-pane>
|
|
|
+ <a-tab-pane key="2" tab="瓦斯抽放">
|
|
|
+ <template>
|
|
|
+ <template>
|
|
|
+ <MonitorTable ref="monitorTable" :columnsType="`${deviceType}_monitor`"
|
|
|
+ :dataSource="dataSource" design-scope="device_monitor" :isShowPagination="false"
|
|
|
+ :isShowActionColumn="isHaveAction.includes(deviceType.split('_')[0]) ? false : true"
|
|
|
+ :is-show-select="false" title="设备监测" :form-config="undefined" :scroll="{ y: 360 }">
|
|
|
+ <template #filterCell="{ column, record }">
|
|
|
+ <template v-if="deviceType.startsWith('gate')">
|
|
|
+ <template
|
|
|
+ v-if="record.frontGateOpenCtrl == 1 || record.frontGateOpenCtrl === true">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
|
|
|
+ color="red">正在打开</a-tag>
|
|
|
+ <a-tag v-else-if="column.dataIndex === 'frontGateOpen'"
|
|
|
+ color="processing">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-else-if="record.frontGateOpenCtrl == 0 || record.frontGateOpenCtrl === false">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 0"
|
|
|
+ color="red">正在关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 0 && record.frontGateClose == 1"
|
|
|
+ color="default">关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'frontGateOpen' && record.frontGateOpen == 1 && record.frontGateClose == 0"
|
|
|
+ color="default">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-if="record.rearGateOpenCtrl == 1 || record.rearGateOpenCtrl === true">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
|
|
|
+ color="red">正在打开</a-tag>
|
|
|
+ <a-tag v-else-if="column.dataIndex === 'rearGateOpen'"
|
|
|
+ color="processing">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ <template
|
|
|
+ v-else-if="record.rearGateOpenCtrl == 0 || record.rearGateOpenCtrl === false">
|
|
|
+ <a-tag
|
|
|
+ v-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 0"
|
|
|
+ color="red">正在关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 0 && record.rearGateClose == 1"
|
|
|
+ color="default">关闭</a-tag>
|
|
|
+ <a-tag
|
|
|
+ v-else-if="column.dataIndex === 'rearGateOpen' && record.rearGateOpen == 1 && record.rearGateClose == 0"
|
|
|
+ color="default">打开</a-tag>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-if="deviceType.startsWith('windrect')">
|
|
|
+ <a-tag v-if="column.dataIndex === 'sign'"
|
|
|
+ :color="record.sign == '0' ? '#95CF65' : record.sign == 1 ? '#4590EA' : '#9876AA'">
|
|
|
+ {{ record.sign == '0' ? '高位' : record.sign == 1 ? '中位' : '低位' }}</a-tag>
|
|
|
+ <template
|
|
|
+ v-if="record && column && column.dataIndex === 'isRun' && record.isRun">
|
|
|
+ <a-tag v-if="record.isRun == -2 || record.isRun == -1"
|
|
|
+ :color="record.isRun == -2 ? '#95CF65' : '#ED5700'">{{
|
|
|
+ record.isRun == -2 ? '空闲' : '等待'
|
|
|
+ }}</a-tag>
|
|
|
+ <a-tag v-else-if="record.isRun == 100" color="#4693FF">完成</a-tag>
|
|
|
+ <Progress v-else :percent="Number(record.isRun)" size="small"
|
|
|
+ status="active" />
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template v-if="deviceType.startsWith('safetymonitor')">
|
|
|
+ <div v-if="!record.devicename && column.dataIndex === 'devicename'">-</div>
|
|
|
+ <div v-if="!record.V && column.dataIndex === 'V'">-</div>
|
|
|
+ <div v-if="!record.PointUnit && column.dataIndex === 'PointUnit'">-</div>
|
|
|
+ <div v-if="!record.highRange && column.dataIndex === 'highRange'">-</div>
|
|
|
+ <div v-if="!record.lowRange && column.dataIndex === 'lowRange'">-</div>
|
|
|
+ <div v-if="!record.dataTypeName && column.dataIndex === 'dataTypeName'">-</div>
|
|
|
+ </template>
|
|
|
+ <a-tag v-if="column.dataIndex === 'warnFlag'"
|
|
|
+ :color="record.warnFlag == '0' ? 'green' : record.warnFlag == 1 ? '#FF5812' : 'gray'">
|
|
|
+ {{ record.warnFlag == '0' ? '正常' : record.warnFlag == 1 ? '报警' : record.warnFlag
|
|
|
+ == 2 ? '断开' : '未监测'
|
|
|
+ }}</a-tag>
|
|
|
+ <a-tag v-if="column.dataIndex === 'netStatus'"
|
|
|
+ :color="record.netStatus == '0' ? '#f00' : 'green'">{{
|
|
|
+ record.netStatus == '0' ? '断开' : '连接'
|
|
|
+ }}</a-tag>
|
|
|
+ </template>
|
|
|
+ </MonitorTable>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </a-tab-pane>
|
|
|
+ </a-tabs>
|
|
|
+
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
- import customHeader from '/@/components/vent/customHeader.vue';
|
|
|
+import { ref, reactive, onMounted, onUnmounted, shallowRef } from 'vue'
|
|
|
+import customHeader from '/@/components/vent/customHeader.vue';
|
|
|
+import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
|
|
|
+import MonitorTable from '../comment/MonitorTable.vue';
|
|
|
+import { cameraAddr, } from '../camera/camera.api'
|
|
|
+import { list } from '../safetyMonitor/safety.api';
|
|
|
+import { formConfig, isHaveAction } from '../safetyMonitor/safety.data';
|
|
|
+import { getDictItemsByCode } from '/@/utils/dict';
|
|
|
+import Player, { I18N } from 'xgplayer';
|
|
|
+import ZH from 'xgplayer/es/lang/zh-cn'
|
|
|
+import HlsPlugin from 'xgplayer-hls';
|
|
|
+import FlvPlugin from 'xgplayer-flv';
|
|
|
+import 'xgplayer/dist/index.min.css';
|
|
|
+import { usePermission } from '/@/hooks/web/usePermission';
|
|
|
+import { useGlobSetting } from '/@/hooks/setting';
|
|
|
+const { hasPermission } = usePermission();
|
|
|
+const { sysOrgCode } = useGlobSetting();
|
|
|
+const activeKey = ref('1'); // tab key
|
|
|
+const deviceType = ref('safetymonitor'); // 监测设备类型
|
|
|
+const dataSource = shallowRef([]); // 实时监测数据
|
|
|
+const monitorTable = ref();
|
|
|
+const playerList = ref([])
|
|
|
+const webRtcServerList = <any[]>[]
|
|
|
+let addrList = ref<{ name: string, addr: string,devicekind:string }[]>([
|
|
|
+ { name: '摄像头1', addr: "http://0.0.0.0:8080/live/16.flv",devicekind:'wasichoufang' },
|
|
|
+ { name: '摄像头2', addr: "http://0.0.0.0:8080/live/17.flv",devicekind:'wasichoufang' }
|
|
|
+])
|
|
|
+I18N.use(ZH)
|
|
|
+
|
|
|
+// https获取监测数据
|
|
|
+let timer: null | NodeJS.Timeout = null;
|
|
|
+function getMonitor(flag?) {
|
|
|
+ if (deviceType.value) {
|
|
|
+ if (timer) timer = null;
|
|
|
+ timer = setTimeout(
|
|
|
+ async () => {
|
|
|
+ await getDataSource();
|
|
|
+ if (timer) {
|
|
|
+ getMonitor();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ flag ? 0 : 1000
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+//tabs选项切换
|
|
|
+async function tabChange(activeKeyVal) {
|
|
|
+ activeKey.value = activeKeyVal;
|
|
|
+ clearTimeout(timer);
|
|
|
+ if (activeKey.value != '1') {
|
|
|
+ deviceType.value = 'wasichoufang'
|
|
|
+
|
|
|
+ } else {
|
|
|
+ deviceType.value = 'safetymonitor'
|
|
|
+ }
|
|
|
+ getMonitor(true);
|
|
|
+}
|
|
|
+//获取安全监控-实时监测数据
|
|
|
+async function getDataSource() {
|
|
|
+ const res = await list({ devicetype: deviceType.value, filterParams: {} });
|
|
|
+ if (res.msgTxt.length > 0) {
|
|
|
+ dataSource.value = [];
|
|
|
+ let dataArr = res.msgTxt[0].datalist || [];
|
|
|
+ dataArr.filter((data: any) => {
|
|
|
+ const readData = data.readData;
|
|
|
+ return Object.assign(data, readData);
|
|
|
+ });
|
|
|
+ if (deviceType.value == 'safetymonitor') {
|
|
|
+ // 如果是安全监控的数据时需要过滤常见设备数据,根据设定的常用安全监控字典去匹配
|
|
|
+ let dictCodes = getDictItemsByCode('safetynormal');
|
|
|
+ let formData = monitorTable.value.getForm();
|
|
|
+ const searchForm = formData.getFieldsValue();
|
|
|
+ if (searchForm && !searchForm['dataTypeName'] && dictCodes && dictCodes.length > 0) {
|
|
|
+ const tempData = [];
|
|
|
+ const tempData1 = [];
|
|
|
+ for (let i = 0; i < dataArr.length; i++) {
|
|
|
+ const item = dataArr[i];
|
|
|
+ let flag = false;
|
|
|
+ for (let i = 0; i < dictCodes.length; i++) {
|
|
|
+ const dict = dictCodes[i];
|
|
|
+ if (dict['value'] == item['dataTypeName']) {
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (flag) {
|
|
|
+ tempData.push(item);
|
|
|
+ } else {
|
|
|
+ tempData1.push(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (sysOrgCode == 'zjtzqctmk' || hasPermission('btn:noGb')) {
|
|
|
+ dataSource.value = [...tempData, ...tempData1];
|
|
|
+ } else {
|
|
|
+ dataSource.value = [...tempData];
|
|
|
+ }
|
|
|
+ dataSource.value = dataSource.value.filter(v => v.strinstallpos == '31102采面钻孔下风侧一氧化碳' || v.strinstallpos == '31102采面钻孔下风侧甲烷')
|
|
|
+
|
|
|
+ } else {
|
|
|
+ dataSource.value = dataArr;
|
|
|
+ dataSource.value = dataArr.filter(v => v.strinstallpos == '31102采面钻孔下风侧一氧化碳' || v.strinstallpos == '31102采面钻孔下风侧甲烷')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dataSource.value = dataArr;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dataSource.value = [];
|
|
|
+ }
|
|
|
+}
|
|
|
+function getVideo() {
|
|
|
+ const ip = VUE_APP_URL.webRtcUrl;
|
|
|
+ for (let i = 0; i < addrList.value.length; i++) {
|
|
|
+ const item = addrList.value[i]
|
|
|
+ if (item.addr.startsWith('rtsp://')) {
|
|
|
+ const dom = document.getElementById('video' + i) as HTMLVideoElement
|
|
|
+ dom.muted = true;
|
|
|
+ dom.volume = 0
|
|
|
+ const webRtcServer = new window['WebRtcStreamer'](dom, location.protocol + ip)
|
|
|
+ webRtcServerList.push(webRtcServer)
|
|
|
+ webRtcServer.connect(item.addr)
|
|
|
+ } else {
|
|
|
+ setNoRtspVideo('player' + i, item.addr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+async function getVideoAddrs() {
|
|
|
+ clearCamera();
|
|
|
+ playerList.value = []
|
|
|
+ const cameraList = <{ name: string, addr: string }[]>[]
|
|
|
+ for (let i = 0; i < addrList.value.length; i++) {
|
|
|
+ const item = addrList.value[i];
|
|
|
+
|
|
|
+ if (item['devicekind'] === 'toHKRtsp') {
|
|
|
+ // 从海康平台接口获取视频流
|
|
|
+ try {
|
|
|
+ const data = await cameraAddr({ cameraCode: item['addr'] });
|
|
|
+ if (data) {
|
|
|
+ cameraList.push({ name: item['name'], addr: data['url'] });
|
|
|
+ }
|
|
|
+ // cameraList.push({
|
|
|
+ // name: item['name'],
|
|
|
+ // // addr: 'http://219.151.31.38/liveplay-kk.rtxapp.com/live/program/live/hnwshd/4000000/mnf.m3u8'
|
|
|
+ // addr: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.mp4/.m3u8',
|
|
|
+ // });
|
|
|
+ } catch (error) {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (item['addr'].includes('0.0.0.0')) {
|
|
|
+ item['addr'] = item['addr'].replace('0.0.0.0', window.location.hostname)
|
|
|
+ }
|
|
|
+ cameraList.push({ name: item['name'], addr: item['addr'] });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+function goFullScreen(domId) {
|
|
|
+ const videoDom = document.getElementById(domId) as HTMLVideoElement
|
|
|
+ if (videoDom.requestFullscreen) {
|
|
|
+ videoDom.requestFullscreen()
|
|
|
+ videoDom.play()
|
|
|
+ } else if (videoDom.mozRequestFullscreen) {
|
|
|
+ videoDom.mozRequestFullscreen()
|
|
|
+ videoDom.play()
|
|
|
+ } else if (videoDom.webkitRequestFullscreen) {
|
|
|
+ videoDom.webkitRequestFullscreen()
|
|
|
+ videoDom.play()
|
|
|
+ } else if (videoDom.msRequestFullscreen) {
|
|
|
+ videoDom.msRequestFullscreen()
|
|
|
+ videoDom.play()
|
|
|
+ }
|
|
|
+}
|
|
|
+function clearCamera() {
|
|
|
+ const num = webRtcServerList.length
|
|
|
+ for (let i = 0; i < num; i++) {
|
|
|
+ webRtcServerList[i].disconnect()
|
|
|
+ webRtcServerList[i] = null
|
|
|
+ }
|
|
|
+ for (let i = 0; i < playerList.value.length; i++) {
|
|
|
+ const player = playerList.value[i]
|
|
|
+ if (player.destroy) player.destroy()
|
|
|
+ }
|
|
|
+ playerList.value = []
|
|
|
+}
|
|
|
+function setNoRtspVideo(id, videoAddr) {
|
|
|
+ const fileExtension = videoAddr.split('.').pop();
|
|
|
+ if (fileExtension === 'flv') {
|
|
|
+ const player = new Player({
|
|
|
+ lang: 'zh',
|
|
|
+ id: id,
|
|
|
+ url: videoAddr,
|
|
|
+ width: 589,
|
|
|
+ height: 330,
|
|
|
+ poster: '/src/assets/images/vent/noSinge.png',
|
|
|
+ plugins: [FlvPlugin],
|
|
|
+ fluid: true,
|
|
|
+ autoplay: true,
|
|
|
+ isLive: true,
|
|
|
+ playsinline: true,
|
|
|
+ screenShot: true,
|
|
|
+ whitelist: [''],
|
|
|
+ ignores: ['time'],
|
|
|
+ closeVideoClick: true,
|
|
|
+ customConfig: {
|
|
|
+ isClickPlayBack: false
|
|
|
+ },
|
|
|
+ flv: {
|
|
|
+ retryCount: 3, // 重试 3 次,默认值
|
|
|
+ retryDelay: 1000, // 每次重试间隔 1 秒,默认值
|
|
|
+ loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
|
|
|
+ fetchOptions: {
|
|
|
+ // 该参数会透传给 fetch,默认值为 undefined
|
|
|
+ mode: 'cors'
|
|
|
+ },
|
|
|
+ targetLatency: 10, // 直播目标延迟,默认 10 秒
|
|
|
+ maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
|
|
|
+ disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
|
|
|
+ maxJumpDistance: 10,
|
|
|
+ }
|
|
|
+ });
|
|
|
+ playerList.value.push(player)
|
|
|
+ }
|
|
|
+ if (fileExtension === 'm3u8') {
|
|
|
+ let player
|
|
|
+ if (document.createElement('video').canPlayType('application/vnd.apple.mpegurl')) {
|
|
|
+ // 原生支持 hls 播放
|
|
|
+ player = new Player({
|
|
|
+ lang: 'zh',
|
|
|
+ id: id,
|
|
|
+ url: videoAddr,
|
|
|
+ width: 589,
|
|
|
+ height: 330,
|
|
|
+ isLive: true,
|
|
|
+ autoplay: true,
|
|
|
+ autoplayMuted: true,
|
|
|
+ cors: true,
|
|
|
+ poster: '/src/assets/images/vent/noSinge.png',
|
|
|
+ hls: {
|
|
|
+ retryCount: 3, // 重试 3 次,默认值
|
|
|
+ retryDelay: 1000, // 每次重试间隔 1 秒,默认值
|
|
|
+ loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
|
|
|
+ fetchOptions: {
|
|
|
+ // 该参数会透传给 fetch,默认值为 undefined
|
|
|
+ mode: 'cors'
|
|
|
+ },
|
|
|
+ targetLatency: 10, // 直播目标延迟,默认 10 秒
|
|
|
+ maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
|
|
|
+ disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
|
|
|
+ maxJumpDistance: 10,
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ } else if (HlsPlugin.isSupported()) { // 第一步
|
|
|
+ player = new Player({
|
|
|
+ lang: 'zh',
|
|
|
+ id: id,
|
|
|
+ url: videoAddr,
|
|
|
+ width: 589,
|
|
|
+ height: 330,
|
|
|
+ isLive: true,
|
|
|
+ autoplay: true,
|
|
|
+ autoplayMuted: true,
|
|
|
+ plugins: [HlsPlugin], // 第二步
|
|
|
+ poster: '/src/assets/images/vent/noSinge.png',
|
|
|
+ hls: {
|
|
|
+ retryCount: 3, // 重试 3 次,默认值
|
|
|
+ retryDelay: 1000, // 每次重试间隔 1 秒,默认值
|
|
|
+ loadTimeout: 10000, // 请求超时时间为 10 秒,默认值
|
|
|
+ fetchOptions: {
|
|
|
+ // 该参数会透传给 fetch,默认值为 undefined
|
|
|
+ mode: 'cors'
|
|
|
+ },
|
|
|
+ targetLatency: 10, // 直播目标延迟,默认 10 秒
|
|
|
+ maxLatency: 20, // 直播允许的最大延迟,默认 20 秒
|
|
|
+ disconnectTime: 10, // 直播断流时间,默认 0 秒,(独立使用时等于 maxLatency)
|
|
|
+ maxJumpDistance: 10,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ playerList.value.push(player)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getVideo()
|
|
|
+ getVideoAddrs()
|
|
|
+ getMonitor(true);
|
|
|
+})
|
|
|
+onUnmounted(() => {
|
|
|
+ clearCamera()
|
|
|
+ if (timer) {
|
|
|
+ clearTimeout(timer);
|
|
|
+ }
|
|
|
+ timer = undefined;
|
|
|
+});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
-.container-ln{
|
|
|
+@import '/@/design/vent/color.less';
|
|
|
+@import '/@/design/vent/modal.less';
|
|
|
+
|
|
|
+.container-ln {
|
|
|
position: relative;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
+ padding: 0px 10px;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .video-ln {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 50%;
|
|
|
+ padding-top: 80px;
|
|
|
+
|
|
|
+ .video-module {
|
|
|
+ width: 45%;
|
|
|
+ height: 100%;
|
|
|
+ background: url('/@/assets/images/vent/camera_bg.png');
|
|
|
+ background-size: 100% 100%;
|
|
|
+
|
|
|
+ .player-name {
|
|
|
+ font-size: 14px;
|
|
|
+ position: absolute;
|
|
|
+ top: 15px;
|
|
|
+ right: 15px;
|
|
|
+ color: #fff;
|
|
|
+ background-color: hsla(0, 0%, 50%, .5);
|
|
|
+ border-radius: 2px;
|
|
|
+ padding: 1px 5px;
|
|
|
+ max-width: 120px;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ z-index: 999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .click-box {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content-ln {
|
|
|
+ width: 100%;
|
|
|
+ height: 50%;
|
|
|
+
|
|
|
+ .tabs-box {
|
|
|
+ width: calc(100% - 12px) !important;
|
|
|
+ height: 100% !important;
|
|
|
+ bottom: 3px !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@ventSpace: zxm;
|
|
|
+
|
|
|
+:deep(.@{ventSpace}-tabs-tabpane-active) {
|
|
|
+ height: 100%;
|
|
|
+ border: 1px solid #44d3ff70;
|
|
|
+ border-radius: 2px;
|
|
|
+ -webkit-backdrop-filter: blur(8px);
|
|
|
+ box-shadow: 0 0 20px #44b4ff33 inset;
|
|
|
+ background-color: #ffffff11;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.@{ventSpace}-tabs-card) {
|
|
|
+ .@{ventSpace}-tabs-tab {
|
|
|
+ background: linear-gradient(#2cd1ff55, #1eb0ff55);
|
|
|
+ border-color: #74e9fe;
|
|
|
+ border-radius: 0%;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #64d5ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-tabs-content {
|
|
|
+ height: 100% !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-tabs-tab.@{ventSpace}-tabs-tab-active .@{ventSpace}-tabs-tab-btn {
|
|
|
+ color: aqua;
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-tabs-nav::before {
|
|
|
+ border-color: #74e9fe;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .@{ventSpace}-table-cell-row-hover {
|
|
|
+ background: #264d8833 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-table-row-selected {
|
|
|
+ background: #00c0a311 !important;
|
|
|
+
|
|
|
+ td {
|
|
|
+ background-color: #00000000 !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-table-thead {
|
|
|
+ // background: linear-gradient(#004a8655 0%, #004a86aa 10%) !important;
|
|
|
+ background: #3d9dd45d !important;
|
|
|
+
|
|
|
+ &>tr>th,
|
|
|
+ .@{ventSpace}-table-column-title {
|
|
|
+ // color: #70f9fc !important;
|
|
|
+ border-color: #84f2ff !important;
|
|
|
+ border-left: none !important;
|
|
|
+ border-right: none !important;
|
|
|
+ padding: 7px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-table-tbody {
|
|
|
+ tr>td {
|
|
|
+ padding: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .@{ventSpace}-table-tbody>tr:hover.@{ventSpace}-table-row>td {
|
|
|
+ background-color: #26648855 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .jeecg-basic-table-row__striped {
|
|
|
+
|
|
|
+ // background: #97efff11 !important;
|
|
|
+ td {
|
|
|
+ background-color: #97efff11 !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|