Newer
Older
safe_production_front / src / views / bigScreen / components / video4.vue
<script lang="ts" setup name="video6">
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import { getConfig } from '@/api/bs'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
const props = defineProps({
  splitScreen: {
    type: Number,
    default: 4,
  },
  showEchart: {
    type: Boolean,
  },
})
const baseurl = ref(window.location.href.split('/#')[0])
const mediaToken = ref('') // 流媒体token
const width = ref(0)
const height = ref(0)
const getConfigData: any = ref([])
const videoUrl = ref(['', '', '', '', '', '']) // 流url
const timers: any = ref([null, null, null, null, null, null]) // 定时器
const currentStreamId = ref(['', '', '', '', '', '']) // 正在播的流的国标号
const resize = () => {
  // const divPlugin = document.getElementById('videoArea') as any
  // height.value = divPlugin.clientHeight / 3 - 1.8
  // width.value = Number(((height.value / 9) * 16).toFixed(2))
  // console.log('宽高', width.value, height.value)
  const divPlugin = document.getElementById('videoArea') as any
  if (props.showEchart) { // 显示下面的图
    height.value = divPlugin.clientHeight / 2
    width.value = Number(((height.value / 9) * 16).toFixed(2))
    console.log('宽高', width.value, height.value)
  }
  else { // 不显示下面的图
    width.value = divPlugin.clientWidth / 2
    height.value = divPlugin.clientHeight / 2
    console.log('宽高', width.value, height.value)
  }
}

// ----------------------------------------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, index: number) {
  const res = await sendHeart(deviceId)
  if (res && res.data) {
    if (`${res.data.status}` !== 'on') { // 停止状态
      if (timers.value[index]) {
        clearInterval(timers.value[index])
      }
    }
  }
}

// 播放流
function playGmStream(cameraIndexCode: string, index: number) {
  if (timers.value[index]) {
    clearInterval(timers.value[index])
  }

  // 播下一个流先停止上一个流
  if (currentStreamId.value[index]) {
    handleStopStream(currentStreamId.value[index])
  }
  // 获取视频流接口
  fetchStream(cameraIndexCode).then((res: any) => {
    const { url, createStreamResponseId } = res
    console.log(`videoUrl.value[${index}]`, url)
    console.log('url字符串拼接', `${url}?token=${window.localStorage.getItem('token')}`)

    videoUrl.value[index] = `${url}?token=${window.localStorage.getItem('token')}`
    console.log(`请求成功url:videoUrl.value[${index}]`, videoUrl.value[index])
    // 记录正在播的流的国标号
    currentStreamId.value[index] = createStreamResponseId
    // 发送心跳
    timers.value[index] = setInterval(() => {
      handleSendHeart(createStreamResponseId, index)
    }, Number(window.localStorage.getItem('timeGap')))
  }).catch(() => {
    console.log('请求失败videoUrl.value[currentIndex]', index)
    ElMessage.warning('未获取到流!请联系管理员!')
  })
}

// ----------------------------------------sm流---------------------------------------------------
// 拉取流(流媒体)
async function fetchMediaStream(deviceId: string, channelId: string, index: number) {
  const res = await getMediaStream(deviceId, channelId, mediaToken.value)
  if (res && res.data) {
    videoUrl.value[index] = res.data.ws_flv
  }
  else {
    ElMessage.warning('设备未注册')
  }
}
// -----------------------------------------------------------------------------------------------
onBeforeUnmount(() => {
  window.removeEventListener('resize', resize)
  // 先停心跳
  if (window.localStorage.getItem('systemType') === 'gm') {
    timers.value.forEach((item: any) => {
      if (item) {
        clearInterval(item)
      }
    })

    // 停所有流
    currentStreamId.value.forEach((item: any) => {
      if (item) {
        handleStopStream(item)
      }
    })
  }
})

// 获取配置并播放
const fetchConfig = async (splitScreen: number) => {
  const res = await getConfig()
  if (res.data) {
    const configData = JSON.parse(res.data)
    getConfigData.value = configData
    if (configData && configData.length) {
      console.log('视频页面:获取设备数据', configData)
      configData.forEach((item: { cameraIndexCode: string; nvrIndexCode: string }, index: number) => {
        // if (currentStreamId.value[currentIndex] !== item.cameraIndexCode && index < 7) {
        // }
        if (index < splitScreen) {
          if (window.localStorage.getItem('systemType') === 'gm') {
            playGmStream(item.cameraIndexCode, index)
          }
          else if (window.localStorage.getItem('systemType') === 'sm') {
            fetchMediaStream(item.cameraIndexCode, item.nvrIndexCode, index)
          }
        }
      })
    }
  }
}
onMounted(async () => {
  if (window.localStorage.getItem('systemType') === 'sm') {
    const res = await getMediaToken()
    mediaToken.value = res.data
  }
  // fetchConfig()
  setTimeout(() => {
    resize()
    window.addEventListener('resize', resize)
  }, 200)
})

watch(() => props.splitScreen, (newValue: number) => {
  if (window.localStorage.getItem('systemType') === 'gm') {
    // 先停心跳
    timers.value.forEach((item: any) => {
      if (item) {
        clearInterval(item)
      }
    })

    // 停所有流
    currentStreamId.value.forEach((item: any) => {
      if (item) {
        handleStopStream(item)
      }
    })
  }
  fetchConfig(newValue)
}, { immediate: true })
</script>

<template>
  <div id="videoArea" class="video-area" :style="{ width: props.showEchart ? `${width * 2}px` : '100%' }">
    <iframe
      v-if="props.splitScreen === 1"
      id="myframe"
      :src="`${baseurl}/player/player.html?playUrl=${videoUrl[0]}`"
      frameborder="0"
      :style="{ width: props.showEchart ? `${width * 2}px` : '100%', height: `${height * 2}px` }"
    />
    <iframe
      v-if="props.splitScreen === 4"
      id="myframe"
      :src="`${baseurl}/playerVideo4/player.html?playUrl1=${videoUrl[0]}&playUrl2=${videoUrl[1]}&playUrl3=${videoUrl[2]}&playUrl4=${videoUrl[3]}`"
      frameborder="0"
      :style="{ width: props.showEchart ? `${width * 2}px` : '100%', height: `${height * 2}px` }"
    />
  </div>
</template>

<style lang="scss" scoped>
.video-area {
  box-sizing: border-box;
  height: 100%;
  z-index: 0;
}
.title {
  position: absolute;
  color: red;
  top: 10rem;
  z-index: 99999;
}
</style>