index.vue 3.01 KB
<template>
  <div>
    <n-spin size="medium" :show="showLoading" :content-style="{ background: 'red' }">
      <template #description> 视频正在努力加载中...... </template>
      <div>
        <VideoPlay ref="videoPlayerRef" :baseSize="{ w, h }" :sourceSrc="sourceUrl" :autoPlay="option.autoplay"
          :avatar="option.poster" />
      </div>
    </n-spin>
  </div>
</template>
<script setup lang="ts">
import { PropType, toRefs, shallowReactive, watch, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { AccessMode, Dataset, option as configOption, sourceTypeEnum } from './config'
import { VideoPlay } from './components'
import { getVideoControlStart } from '@/api/external/flvPlay'
import { getVideoUrl } from '@/api/external/common'

const props = defineProps({
  chartConfig: {
    type: Object as PropType<CreateComponentType>,
    required: true
  }
})

const showLoading = ref(false)

const { w, h } = toRefs(props.chartConfig.attr)

const { autoplay, dataset, poster, customVideoUrl } = toRefs(props.chartConfig.option as typeof configOption)

const option = shallowReactive({
  dataset: configOption.dataset,
  poster: configOption.poster,
  autoplay: configOption.autoplay
})

const sourceUrl = ref('')
const videoPlayerRef = ref<InstanceType<typeof VideoPlay> | null>()

// 针对萤石云或者海康威视,根据视频id获取播放流地址
const getVideoUrlById = async (id: string) => {
  const res = await getVideoUrl(id)
  if (!res) return
  const { url } = res.data
  return url
}

// 针对gbt28181,根据设备id和通道号获取播放流地址
const getVideoControlList = async (deviceId: string, channelId: string) => {
  const {
    data: { flv }
  } = await getVideoControlStart({
    deviceId,
    channelId
  })
  return flv
}

// 针对自定义地址,直接获取地址
const getCustomUrl = (url: string) => {
  return url
}


async function getPlaySource(params: Dataset) {
  try {
    showLoading.value = true

    const { accessMode, id, deviceId, channelId, customUrl } = params
    if (accessMode === AccessMode.Streaming && id) {
      return await getVideoUrlById(id!)
    } else if (accessMode === AccessMode.GBT28181 && deviceId && channelId) {
      return await getVideoControlList(deviceId!, channelId!)
    } else {
      return getCustomUrl(customUrl!)
    }
  } finally {
    showLoading.value = false
  }
}

watch(
  () => dataset?.value,
  async (newData) => {
    videoPlayerRef.value?.dispose()
    sourceUrl.value = await getPlaySource(newData)
    videoPlayerRef.value?.anewInit()
  },
  {
    immediate: true
  }
)

watch(
  () => customVideoUrl.value,
   (newData) => {
     if(newData){
      videoPlayerRef.value?.dispose()
      sourceUrl.value = newData;
      videoPlayerRef.value?.anewInit()
    }
  },
  {
    immediate: true
  }
)

watch(
  () => [poster.value, autoplay.value],
  newData => {
    option.poster = newData.at(-2) as string
    option.autoplay = newData.at(-1) as boolean
  },
  {
    immediate: true
  }
)
</script>

<style lang="scss" scoped>
</style>