<!-- Description: 视频播放-img-ws Author: 李亚光 Date: 2024-11-11 --> <script lang="ts" setup name="VideoPlayer"> import axios from 'axios' import { getSceneList } from '@/api/page/scene' import { getSceneRelations } from '@/api/page/device' import drawArea from '../../device/components/drawArea.vue' const $props = defineProps({ id: { type: String, required: true, }, status: { type: String, default: '', }, sence: { type: String, default: '', } }) const publicPath = window.location.href.split('#')[0] const src = ref(`${publicPath}/image/normal.png`) const webSocket = ref() watch(() => $props.id, (newVal) => { // console.log(newVal, 'newValid') if (!newVal) { src.value = `${publicPath}/image/nodata.png` return } if ($props.status === '离线') { src.value = `${publicPath}/image/offline.png` return } if ($props.status !== '在线') { src.value = `${publicPath}/image/normal.png` return } if (Number(newVal)) { src.value = `${publicPath}/image/loading.gif` // axios.get(`${window.localStorage.getItem('IntegratedFront')}/api/display/video?device_id=${newVal}`).then((res) => { // console.log(res, 'resresres') setTimeout(() => { src.value = `${window.localStorage.getItem('IntegratedFront')}/api/display/video?device_id=${newVal}` }, 1000) // }) // .catch(() => { // src.value = `${publicPath}/image/error.png` // }) } else { src.value = `${publicPath}/image/normal.png` } }, { deep: true, immediate: true, }) const elementId = ref(`ele-${new Date().getTime()}`) const timer = ref() const showArea = ref(false) const drawRef = ref() const drawWidth = ref(0) const drawHieght = ref(0) watch(() => $props.sence, (newVal) => { if (newVal) { if (timer.value) { clearInterval(timer.value) timer.value = null } timer.value = setInterval(() => { // console.log(newVal, 'newValsence') // 判断视频状态 if ($props.status !== '在线' || !$props.id) { return } // console.log(src.value, 'src.value') const img = document.getElementById(elementId.value) as HTMLImageElement console.log(img.complete, 'img.complete') if (!img.complete || src.value.includes('loading') || src.value.includes('error') || src.value.includes('nodata') || src.value.includes('normal')) { return } clearInterval(timer.value) timer.value = null // 画框 // getSceneList({ offset: 1, limit: 999 }).then(res => { // const current = res.data.items.filter((item: any) => item.name === newVal)[0] || {} // if (current.name) { // console.log(current, 'current') // } // }) // 获取图片的宽高 getSceneRelations({ id: $props.id }).then(res => { // console.log(res.data, '框的数据') const img = document.getElementById(elementId.value) if (img) { if (!img.offsetWidth) { return } // 图片分辨率 const width = img.naturalWidth const height = img.naturalHeight const resolution = width / height console.log(width, height, '图片分辨率') // 获取图片父元素 const container = img.parentNode console.log(container.offsetWidth, '父元素') img.style.width = `${container.offsetWidth}px` img.style.height = `${img.offsetWidth / resolution}px` drawWidth.value = img.offsetWidth drawHieght.value = img.offsetHeight } showArea.value = true setTimeout(() => { if(!res.data?.range_points || !res.data) { return } drawRef.value.setPonits(res.data.range_points) }, 1000) }) }, 1500); } }, { deep: true, immediate: true }) onUnmounted(() => { if (webSocket.value) { webSocket.value.close() webSocket.value = '' src.value = `${publicPath}/image/normal.png` } clearInterval(timer.value) timer.value = null }) const errorImage = () => { console.log('加载失败') src.value = `${publicPath}/image/error.png` } </script> <template> <div style="width: 100%;height: 100%;position: relative;background-color: #1B1717;overflow: hidden;"> <img :id="elementId" :src="src" style="width: 100%; height: 100%; background-color: rgb(0 0 0 / 70%); position: absolute; left: 0; top: 50%;transform: translateY(-50%);" alt="视频流" object-fit="cover" @error="errorImage"> <drawArea v-if="showArea" :width="drawWidth" :height="drawHieght" ref="drawRef" style="position: absolute; left: 0; top: 50%;transform: translateY(-50%);" /> </div> <!-- <el-image style="width: 100%; height: 100%; background-color: rgb(0 0 0 / 70%);" :src="src" fit="fill" /> --> </template>