diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/src/layouts/components/Tools/index.vue b/src/layouts/components/Tools/index.vue index 56c513a..0b3506b 100644 --- a/src/layouts/components/Tools/index.vue +++ b/src/layouts/components/Tools/index.vue @@ -163,13 +163,13 @@ --> -
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
-
- {{ userStore.name }} + -
- + +
diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/src/layouts/components/Tools/index.vue b/src/layouts/components/Tools/index.vue index 56c513a..0b3506b 100644 --- a/src/layouts/components/Tools/index.vue +++ b/src/layouts/components/Tools/index.vue @@ -163,13 +163,13 @@ -->
-
- {{ userStore.name }} + -
- + +
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue index cb66292..110dcab 100644 --- a/src/views/alarm/dangerAssessment/manage/list.vue +++ b/src/views/alarm/dangerAssessment/manage/list.vue @@ -79,7 +79,7 @@ // 危险作业 const columnsWork: TableColumn[] = [ { text: '所属单位', value: 'deptName', align: 'center' }, - { text: '危险作业', value: 'hazardousHork', align: 'center' }, + { text: '危险作业', value: 'hazardousWork', align: 'center' }, { text: '危险作业等级', value: 'workLevel', align: 'center' }, { text: '主要危险描述', value: 'hazardousRemark', align: 'center' }, { text: '相关部门', value: 'relevantDepartments', align: 'center' }, diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/src/layouts/components/Tools/index.vue b/src/layouts/components/Tools/index.vue index 56c513a..0b3506b 100644 --- a/src/layouts/components/Tools/index.vue +++ b/src/layouts/components/Tools/index.vue @@ -163,13 +163,13 @@ -->
-
- {{ userStore.name }} + -
- + +
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue index cb66292..110dcab 100644 --- a/src/views/alarm/dangerAssessment/manage/list.vue +++ b/src/views/alarm/dangerAssessment/manage/list.vue @@ -79,7 +79,7 @@ // 危险作业 const columnsWork: TableColumn[] = [ { text: '所属单位', value: 'deptName', align: 'center' }, - { text: '危险作业', value: 'hazardousHork', align: 'center' }, + { text: '危险作业', value: 'hazardousWork', align: 'center' }, { text: '危险作业等级', value: 'workLevel', align: 'center' }, { text: '主要危险描述', value: 'hazardousRemark', align: 'center' }, { text: '相关部门', value: 'relevantDepartments', align: 'center' }, diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue index fdf9ea0..dee9056 100644 --- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue +++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue @@ -41,11 +41,12 @@ ctx.lineTo(e.boundary[3].x, e.boundary[3].y) } // ctx.strokeStyle = e.pointColor - ctx.strokeStyle = e.pointColor || '#3d7eff' + ctx.strokeStyle = e.pointColor || '#1aa034' ctx.closePath() - ctx.font = '13px Arial' + // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial' + ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑' // ctx.fillStyle = e.pointColor - ctx.fillStyle = e.pointColor || '#3d7eff' + ctx.fillStyle = e.pointColor || '#1aa034' // const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y) // const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x) const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3 @@ -53,7 +54,7 @@ ctx.fillText(e.remark, textX, textY) }) } - ctx.lineWidth = 1 + ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2 ctx.stroke() } @@ -207,8 +208,8 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; - opacity: 0.5; + background-color: #1aa034; + opacity: 0.8; top: 0; left: 0; z-index: 99; @@ -222,7 +223,7 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; + background-color: #1aa034; opacity: 0.5; top: 0; left: 0; diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/src/layouts/components/Tools/index.vue b/src/layouts/components/Tools/index.vue index 56c513a..0b3506b 100644 --- a/src/layouts/components/Tools/index.vue +++ b/src/layouts/components/Tools/index.vue @@ -163,13 +163,13 @@ -->
-
- {{ userStore.name }} + -
- + +
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue index cb66292..110dcab 100644 --- a/src/views/alarm/dangerAssessment/manage/list.vue +++ b/src/views/alarm/dangerAssessment/manage/list.vue @@ -79,7 +79,7 @@ // 危险作业 const columnsWork: TableColumn[] = [ { text: '所属单位', value: 'deptName', align: 'center' }, - { text: '危险作业', value: 'hazardousHork', align: 'center' }, + { text: '危险作业', value: 'hazardousWork', align: 'center' }, { text: '危险作业等级', value: 'workLevel', align: 'center' }, { text: '主要危险描述', value: 'hazardousRemark', align: 'center' }, { text: '相关部门', value: 'relevantDepartments', align: 'center' }, diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue index fdf9ea0..dee9056 100644 --- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue +++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue @@ -41,11 +41,12 @@ ctx.lineTo(e.boundary[3].x, e.boundary[3].y) } // ctx.strokeStyle = e.pointColor - ctx.strokeStyle = e.pointColor || '#3d7eff' + ctx.strokeStyle = e.pointColor || '#1aa034' ctx.closePath() - ctx.font = '13px Arial' + // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial' + ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑' // ctx.fillStyle = e.pointColor - ctx.fillStyle = e.pointColor || '#3d7eff' + ctx.fillStyle = e.pointColor || '#1aa034' // const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y) // const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x) const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3 @@ -53,7 +54,7 @@ ctx.fillText(e.remark, textX, textY) }) } - ctx.lineWidth = 1 + ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2 ctx.stroke() } @@ -207,8 +208,8 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; - opacity: 0.5; + background-color: #1aa034; + opacity: 0.8; top: 0; left: 0; z-index: 99; @@ -222,7 +223,7 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; + background-color: #1aa034; opacity: 0.5; top: 0; left: 0; diff --git a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue index 3cb33d1..9b80f6e 100644 --- a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue +++ b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue @@ -6,6 +6,7 @@ import type { FormInstance, FormRules } from 'element-plus' import type { IForm, IList } from './monitorPoint-interface' import drawArea from './drawArea.vue' +import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm' import type { TableColumn } from '@/components/NormalTable/table_interface' import { isIp } from '@/utils/validate' import { getMediaStream, getMediaToken } from '@/api/monitor/media' @@ -14,7 +15,10 @@ const emits = defineEmits(['closeRefresh']) const dialogStatus = ref('add') const baseurl = ref(window.location.href.split('/#')[0]) +const timer = ref() // gm取流定时器 const dialogVisible = ref(false) // 弹窗显示隐藏 +const systemType = ref('') // 系统类别 +const currentStreamId = ref('') // 正在播的流的国标号 const mediaToken = ref('') // 流媒体token const mediaUrl = ref('') // 流媒体url const cameraIndexCode = ref('') // 设备国标号 @@ -291,6 +295,7 @@ // -----------------------------------初始化、关闭对话框相关----------------------------------------- function initDialog(dialogstatus: string, row: any) { + systemType.value = window.localStorage.getItem('systemType') as string dialogVisible.value = true fetchEdgeDeviceList() // 获取边缘设备列表 fetchAlgorithmList() // 获取算法列表 @@ -357,14 +362,28 @@ dialogStatus.value = dialogstatus // 类型 新建add 编辑edit 详情detail cameraIndexCode.value = row.cameraIndexCode || '' // 设备国标号 nvrIndexCode.value = row.nvrIndexCode || '' // nvr国标号 - if (cameraIndexCode.value && nvrIndexCode.value) { + if (systemType.value === 'sm' && cameraIndexCode.value && nvrIndexCode.value) { // 流媒体 fetchMediaStream(cameraIndexCode.value, nvrIndexCode.value) } + if (systemType.value === 'gm' && cameraIndexCode.value) { // gm取流 + playGmStream(cameraIndexCode.value) + } btnLoading.value = false } // 关闭并刷新 function closeRefresh() { + if (systemType.value === 'gm') { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + } drawAreaRef.value.removeCanvas() dialogVisible.value = false mediaToken.value = '' // 流媒体token @@ -413,7 +432,7 @@ formData.value.algoModelId = '' // 模型id recognitionList.value = [] // 清空表格 } -// ----------------------------------------------取流--------------------------------------------------------- +// ----------------------------------------------流媒体取流--------------------------------------------------------- // 拉取流--普通流 async function fetchMediaStream(deviceId: string, channelId: string) { // 获取流媒体token @@ -428,6 +447,68 @@ ElMessage.warning('设备未注册') } } +// ----------------------------------------gm流--------------------------------------------------- +// 创建流 +async function fetchStream(deviceId: string) { + const res = await createStream(deviceId) + if (res && res.data) { + return { + url: res.data.url, + createStreamResponseId: res.data.id, + } + } + else { + ElMessage.warning('创建流失败!') + } +} + +// 停止流 +async function handleStopStream(deviceId: string) { + const res = await stopStream(deviceId) + if (res.code !== 200) { + ElMessage.warning('停止流失败!') + } +} + +// 发送心跳 +async function handleSendHeart(deviceId: string) { + const res = await sendHeart(deviceId) + if (res && res.data) { + if (`${res.data.status}` !== 'on') { // 停止状态 + if (timer.value) { + clearInterval(timer.value) + } + } + } +} + +// 播放流 +function playGmStream(cameraIndexCode: string) { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + // 获取视频流接口 + fetchStream(cameraIndexCode).then((res: any) => { + const { url, createStreamResponseId } = res + mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}` + // 记录正在播的流的国标号 + currentStreamId.value = createStreamResponseId + + // 发送心跳 + timer.value = setInterval(() => { + handleSendHeart(createStreamResponseId) + }, Number(window.localStorage.getItem('timeGap'))) + }).catch(() => { + ElMessage.warning('未获取到流!请联系管理员!') + }) +} +// ----------------------------------------------------------------------------------------------- // ---------------------------------------------- 以下是暴露的方法内容 --------------------------------------------------------- defineExpose({ initDialog }) @@ -642,5 +723,6 @@ margin: 0; box-sizing: content-box; position: relative; + background-color: #161616; } diff --git a/public/config/config.json b/public/config/config.json index 12a6978..33afb5e 100644 --- a/public/config/config.json +++ b/public/config/config.json @@ -6,9 +6,11 @@ "lng-bd": "116.26499505", "lat": "39.90", "lng": "116.39", - "minZoom": "3", - "maxZoom": "13", - "zoom": "10", + "minZoom": "1", + "maxZoom": "18", + "zoom": "15", "timeGap": 3000, - "systemType": "gm" + "systemType": "gm", + "lineWidth": "3", + "fontSize": "18px" } diff --git a/src/layouts/components/Tools/index.vue b/src/layouts/components/Tools/index.vue index 56c513a..0b3506b 100644 --- a/src/layouts/components/Tools/index.vue +++ b/src/layouts/components/Tools/index.vue @@ -163,13 +163,13 @@ -->
-
- {{ userStore.name }} + -
- + +
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue index cb66292..110dcab 100644 --- a/src/views/alarm/dangerAssessment/manage/list.vue +++ b/src/views/alarm/dangerAssessment/manage/list.vue @@ -79,7 +79,7 @@ // 危险作业 const columnsWork: TableColumn[] = [ { text: '所属单位', value: 'deptName', align: 'center' }, - { text: '危险作业', value: 'hazardousHork', align: 'center' }, + { text: '危险作业', value: 'hazardousWork', align: 'center' }, { text: '危险作业等级', value: 'workLevel', align: 'center' }, { text: '主要危险描述', value: 'hazardousRemark', align: 'center' }, { text: '相关部门', value: 'relevantDepartments', align: 'center' }, diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue index fdf9ea0..dee9056 100644 --- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue +++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue @@ -41,11 +41,12 @@ ctx.lineTo(e.boundary[3].x, e.boundary[3].y) } // ctx.strokeStyle = e.pointColor - ctx.strokeStyle = e.pointColor || '#3d7eff' + ctx.strokeStyle = e.pointColor || '#1aa034' ctx.closePath() - ctx.font = '13px Arial' + // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial' + ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑' // ctx.fillStyle = e.pointColor - ctx.fillStyle = e.pointColor || '#3d7eff' + ctx.fillStyle = e.pointColor || '#1aa034' // const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y) // const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x) const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3 @@ -53,7 +54,7 @@ ctx.fillText(e.remark, textX, textY) }) } - ctx.lineWidth = 1 + ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2 ctx.stroke() } @@ -207,8 +208,8 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; - opacity: 0.5; + background-color: #1aa034; + opacity: 0.8; top: 0; left: 0; z-index: 99; @@ -222,7 +223,7 @@ height: 10px; position: absolute; border-radius: 50%; - background-color: #3d7eff; + background-color: #1aa034; opacity: 0.5; top: 0; left: 0; diff --git a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue index 3cb33d1..9b80f6e 100644 --- a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue +++ b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue @@ -6,6 +6,7 @@ import type { FormInstance, FormRules } from 'element-plus' import type { IForm, IList } from './monitorPoint-interface' import drawArea from './drawArea.vue' +import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm' import type { TableColumn } from '@/components/NormalTable/table_interface' import { isIp } from '@/utils/validate' import { getMediaStream, getMediaToken } from '@/api/monitor/media' @@ -14,7 +15,10 @@ const emits = defineEmits(['closeRefresh']) const dialogStatus = ref('add') const baseurl = ref(window.location.href.split('/#')[0]) +const timer = ref() // gm取流定时器 const dialogVisible = ref(false) // 弹窗显示隐藏 +const systemType = ref('') // 系统类别 +const currentStreamId = ref('') // 正在播的流的国标号 const mediaToken = ref('') // 流媒体token const mediaUrl = ref('') // 流媒体url const cameraIndexCode = ref('') // 设备国标号 @@ -291,6 +295,7 @@ // -----------------------------------初始化、关闭对话框相关----------------------------------------- function initDialog(dialogstatus: string, row: any) { + systemType.value = window.localStorage.getItem('systemType') as string dialogVisible.value = true fetchEdgeDeviceList() // 获取边缘设备列表 fetchAlgorithmList() // 获取算法列表 @@ -357,14 +362,28 @@ dialogStatus.value = dialogstatus // 类型 新建add 编辑edit 详情detail cameraIndexCode.value = row.cameraIndexCode || '' // 设备国标号 nvrIndexCode.value = row.nvrIndexCode || '' // nvr国标号 - if (cameraIndexCode.value && nvrIndexCode.value) { + if (systemType.value === 'sm' && cameraIndexCode.value && nvrIndexCode.value) { // 流媒体 fetchMediaStream(cameraIndexCode.value, nvrIndexCode.value) } + if (systemType.value === 'gm' && cameraIndexCode.value) { // gm取流 + playGmStream(cameraIndexCode.value) + } btnLoading.value = false } // 关闭并刷新 function closeRefresh() { + if (systemType.value === 'gm') { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + } drawAreaRef.value.removeCanvas() dialogVisible.value = false mediaToken.value = '' // 流媒体token @@ -413,7 +432,7 @@ formData.value.algoModelId = '' // 模型id recognitionList.value = [] // 清空表格 } -// ----------------------------------------------取流--------------------------------------------------------- +// ----------------------------------------------流媒体取流--------------------------------------------------------- // 拉取流--普通流 async function fetchMediaStream(deviceId: string, channelId: string) { // 获取流媒体token @@ -428,6 +447,68 @@ ElMessage.warning('设备未注册') } } +// ----------------------------------------gm流--------------------------------------------------- +// 创建流 +async function fetchStream(deviceId: string) { + const res = await createStream(deviceId) + if (res && res.data) { + return { + url: res.data.url, + createStreamResponseId: res.data.id, + } + } + else { + ElMessage.warning('创建流失败!') + } +} + +// 停止流 +async function handleStopStream(deviceId: string) { + const res = await stopStream(deviceId) + if (res.code !== 200) { + ElMessage.warning('停止流失败!') + } +} + +// 发送心跳 +async function handleSendHeart(deviceId: string) { + const res = await sendHeart(deviceId) + if (res && res.data) { + if (`${res.data.status}` !== 'on') { // 停止状态 + if (timer.value) { + clearInterval(timer.value) + } + } + } +} + +// 播放流 +function playGmStream(cameraIndexCode: string) { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + // 获取视频流接口 + fetchStream(cameraIndexCode).then((res: any) => { + const { url, createStreamResponseId } = res + mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}` + // 记录正在播的流的国标号 + currentStreamId.value = createStreamResponseId + + // 发送心跳 + timer.value = setInterval(() => { + handleSendHeart(createStreamResponseId) + }, Number(window.localStorage.getItem('timeGap'))) + }).catch(() => { + ElMessage.warning('未获取到流!请联系管理员!') + }) +} +// ----------------------------------------------------------------------------------------------- // ---------------------------------------------- 以下是暴露的方法内容 --------------------------------------------------------- defineExpose({ initDialog }) @@ -642,5 +723,6 @@ margin: 0; box-sizing: content-box; position: relative; + background-color: #161616; } diff --git a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue index bfa7da7..a16585e 100644 --- a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue +++ b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue @@ -4,14 +4,18 @@ import { ElMessage, ElMessageBox } from 'element-plus' import dayjs from 'dayjs' import { getSecurityAlarmList } from '@/api/alarm/securityAlarm/securityAlarmList' +import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm' import { getMediaStream, getMediaToken } from '@/api/monitor/media' import { videoTree } from '@/api/monitor/broadcast' import drawArea from '@/views/alarm/policyConfig/monitorPoint/drawArea.vue' +const timer = ref() // gm取流定时器 const router = useRouter() const baseurl = ref(window.location.href.split('/#')[0]) const treeRef = ref(null) as any const filterText = ref('') +const systemType = ref('') // 系统类别 const data = ref([]) +const currentStreamId = ref('') // 正在播的流的国标号 const points = ref() // 标注信息 // const palyUrl = `${url}?token=${window.localStorage.getItem('token')}` @@ -60,6 +64,7 @@ let treeClickCount = 0 // 用于双击事件判断 +// 双击树节点 function handleNodeClick(data: any, node: any, self: any) { console.log('设备信息', data) @@ -76,25 +81,32 @@ if (data.device.id === currentLeafId.value) { return } - leafLoading.value = true + leafLoading.value = true // 叶子结点加载流的时候显示Loading图标 currentLeafId.value = data.device.id currentData.value = data.device title.value = data.device.monitorName.replace('-', ' - ') + // -------------------------------区域绘制---------------------------------------- if (data.device.deviceBoundaryDTOS && data.device.deviceBoundaryDTOS.length) { draw(data.device.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary)) } else { points.value = [] } + // -------------------------------区域绘制---------------------------------------- if (radio.value === '1') { // 原始流 - // 获取原始流 - fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => { - leafLoading.value = false - mediaUrl.value = res - }).catch(() => { - ElMessage.warning('未获取到流!请联系管理员!') - leafLoading.value = false - }) + if (systemType.value === 'sm') { // 商米流媒体 + // 获取原始流 + fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => { + leafLoading.value = false + mediaUrl.value = res + }).catch(() => { + ElMessage.warning('未获取到流!请联系管理员!') + leafLoading.value = false + }) + } + else if (systemType.value === 'gm') { // 国米 + playGmStream(data.device.cameraIndexCode) + } } else if (radio.value === '2') { // 识别流 mediaUrl.value = data.device.recognitionUrl @@ -103,7 +115,8 @@ treeClickCount = now } -// 拉取流 +// ----------------------------------------流媒体--------------------------------------------------- +// 拉取流(流媒体) async function fetchMediaStream(deviceId: string, channelId: string) { loading.value = true const res = await getMediaStream(deviceId, channelId, mediaToken.value) @@ -115,6 +128,72 @@ ElMessage.warning('设备未注册') } } +// ----------------------------------------gm流--------------------------------------------------- +// 创建流 +async function fetchStream(deviceId: string) { + loading.value = true + const res = await createStream(deviceId) + loading.value = false + if (res && res.data) { + return { + url: res.data.url, + createStreamResponseId: res.data.id, + } + } + else { + ElMessage.warning('创建流失败!') + } +} + +// 停止流 +async function handleStopStream(deviceId: string) { + const res = await stopStream(deviceId) + if (res.code !== 200) { + ElMessage.warning('停止流失败!') + } +} + +// 发送心跳 +async function handleSendHeart(deviceId: string) { + const res = await sendHeart(deviceId) + if (res && res.data) { + if (`${res.data.status}` !== 'on') { // 停止状态 + if (timer.value) { + clearInterval(timer.value) + } + } + } +} + +// 播放流 +function playGmStream(cameraIndexCode: string) { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + // 获取视频流接口 + fetchStream(cameraIndexCode).then((res: any) => { + leafLoading.value = false + const { url, createStreamResponseId } = res + mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}` + // 记录正在播的流的国标号 + currentStreamId.value = createStreamResponseId + + // 发送心跳 + timer.value = setInterval(() => { + handleSendHeart(createStreamResponseId) + }, Number(window.localStorage.getItem('timeGap'))) + }).catch(() => { + ElMessage.warning('未获取到流!请联系管理员!') + leafLoading.value = false + }) +} +// ----------------------------------------------------------------------------------------------- // 获取当日报警数数据 const fetchAlarmData = () => { @@ -145,17 +224,33 @@ points.value = [] // 清除标注信息 draw(currentData.value.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary)) if (val === '1') { // 原始流 - // 获取原始流 - leafLoading.value = true - fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => { - leafLoading.value = false - mediaUrl.value = res - }).catch(() => { - ElMessage.warning('未获取到流!请联系管理员!') - leafLoading.value = false - }) + if (systemType.value === 'sm') { // 流媒体 + // 获取原始流 + leafLoading.value = true + fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => { + leafLoading.value = false + mediaUrl.value = res + }).catch(() => { + ElMessage.warning('未获取到流!请联系管理员!') + leafLoading.value = false + }) + } + else if (systemType.value === 'gm') { // 国米 + playGmStream(currentData.value.cameraIndexCode) + } } else if (val === '2') { // 识别流 + if (systemType.value === 'gm') { // gm切换识别流先清心跳和正在播放的流 + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + } mediaUrl.value = currentData.value.recognitionUrl } } @@ -199,18 +294,32 @@ onBeforeUnmount(() => { unwatch() window.removeEventListener('resize', resize) + if (systemType.value === 'gm') { + // 先停心跳 + if (timer.value) { + clearInterval(timer.value) + } + + // 播下一个流先停止上一个流 + if (currentStreamId.value) { + handleStopStream(currentStreamId.value) + } + } }) onMounted(() => { + systemType.value = window.localStorage.getItem('systemType') as string videoTree().then((response) => { if (response.code === 200) { data.value = response.data } }) - // 获取流媒体token - getMediaToken().then((res: any) => { - mediaToken.value = res.data - }) + if (systemType.value === 'sm') { + // 获取流媒体token + getMediaToken().then((res: any) => { + mediaToken.value = res.data + }) + } setTimeout(() => { resize() window.addEventListener('resize', resize) @@ -285,7 +394,7 @@
-
+