Newer
Older
safe_production_front / src / views / ycjg / ssjk / control-new-gm-plugin.vue
dutingting on 25 Oct 5 KB gm视频调试
<!-- 流媒体 -->
<script lang="ts" setup name="videoControl">
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Ref } from 'vue'
import { ref } from 'vue'
import { debounce } from 'lodash-es'
import { createStream, sendHeart, stopStream } from '@/api/ycjg/index-new-gm'
import useWebsocketStore from '@/store/modules/websocket'
import { getDevInfo } from '@/api/ptz/dev'
const websocket = useWebsocketStore()
const $route = useRoute()
const deviceData: Ref<any> = ref({})
const currentStreamId = ref('') // 正在播的流的国标号
const refreshHK = ref(true)
const videoUrl = ref('')
const timer = ref(null) as any
const listQuery = ref({
  devId: '',
  startTime: '',
  endTime: '',
  offset: 1,
  limit: 6,
})
const baseurl = ref(window.location.href.split('/#')[0])
console.log('baseurl', baseurl.value)
// socket更新数据
const unwatch = watch(websocket, (newVal) => {
})

// 调整大小
const resize = debounce(() => {
  // if (deviceData.value.nvrManufacture === 'HIKVISION') {
  //   stop(0)
  //   refreshHK.value = true
  //   nextTick(() => {
  //     initPlugin(hkPlugin.value.clientWidth, hkPlugin.value.clientHeight, 1, '', false, () => {
  //       setTimeout(() => {
  //         preview(deviceData.value.nvrIp, '80', deviceData.value.nvrUser, deviceData.value.nvrPassword, 0, true, deviceData.value.nvrChannel)
  //       }, 1000)
  //     }, () => {
  //     })
  //   })
  // }
}, 1000)

const handleResize = () => {
  if (deviceData.value.nvrManufacture === 'HIKVISION') {
    refreshHK.value = false
  }
  resize()
}

// 拉取流
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') { // 停止状态
      clearInterval(timer.value)
    }
  }
}

onMounted(() => {
  if ($route.query && $route.query.id) {
    listQuery.value.devId = $route.query.id!.toString()
    getDevInfo(listQuery.value.devId).then((response) => {
      deviceData.value = response.data
      setTimeout(() => {
        // 获取视频流接口
        fetchStream(deviceData.value.cameraIndexCode).then((res: any) => {
          console.log('获取到流地址', res)
          const { url, createStreamResponseId } = res

          videoUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
          // 记录正在播的流的国标号
          currentStreamId.value = createStreamResponseId

          // 发送心跳
          if (timer.value) {
            clearInterval(timer.value)
          }
          timer.value = setInterval(() => {
            handleSendHeart(createStreamResponseId)
          }, Number(window.localStorage.getItem('timeGap')))
        }).catch(() => {
          ElMessage.warning('未获取到流!请联系管理员!')
        })
        handleResize()
        window.addEventListener('resize', handleResize)
      }, 200)
    })
  }
})

onBeforeUnmount(() => {
  unwatch()
  window.removeEventListener('resize', resize)
  clearInterval(timer.value)
  // 停止正在播放的流
  if (currentStreamId.value) {
    handleStopStream(currentStreamId.value)
  }
})
</script>

<template>
  <div class="video-wrap" style="height: calc(100vh - 214px)">
    <iframe
      :src="`${baseurl}/player/player.html?playUrl=${videoUrl}`"
      frameborder="0"
      style="width: calc(100% - 10px); height: 100%"
    />
    <!-- <video id="myVideo" :src="videoUrl" controls muted autoPlay class="videoControl" /> -->
    <div class="bottom">
      <div style="width: 100%;height: 100%;display: flex;background-color: rgb(255 255 255 / 65%);border-radius: 10px;">
        <el-tabs tab-position="left" style="height: 100%;width: 100%;">
          <el-tab-pane label="设备信息">
            <el-descriptions style="flex: 1;" class="margin-top" :column="3" border>
              <el-descriptions-item label="设备名称">
                {{ deviceData.monitorName }}
              </el-descriptions-item>
              <el-descriptions-item label="设备类型">
                {{ deviceData.deviceTypeName }}
              </el-descriptions-item>
              <el-descriptions-item label="所属单位">
                {{ deviceData.deptName }}
              </el-descriptions-item>
              <el-descriptions-item label="所属区域">
                {{ deviceData.areaName }}
              </el-descriptions-item>
              <el-descriptions-item label="经度">
                {{ deviceData.longitude }}
              </el-descriptions-item>
              <el-descriptions-item label="纬度">
                {{ deviceData.latitude }}
              </el-descriptions-item>
              <el-descriptions-item label="位置">
                {{ deviceData.location }}
              </el-descriptions-item>
              <el-descriptions-item label="备注">
                {{ deviceData.description }}
              </el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.video-wrap {
  display: flex;
  flex-wrap: wrap;
  padding: 10px;
}

.videoControl {
  height: calc(100% - 165px);
  // width: calc(100% - 390px);
  width: calc(100% - 20px);
  margin-left: 10px;
  margin-top: 10px;
  position: absolute;
  background-color: #111;
}

.bottom {
  width: calc(100% - 10px);
  height: 140px;
  position: absolute;
  left: 0;
  bottom: 5px;
  display: flex;
  border-radius: 10px;
  margin: 5px;
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
  overflow: hidden;
  padding: 5px;
  justify-content: space-between;
}
</style>