144 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, watch, onMounted, onUnmounted, computed } from 'vue';
import { isEmpty, getAssetsFile } from '@/utils';
import { useRoute, useRouter } from 'vue-router';
import Hls from 'hls.js';
const route = useRoute();
const router = useRouter();
const currentDevice = ref(0);
const currentPicture = ref(0);
const videoPlayer = ref(null);
const hls = ref(null);
const loading = ref(false);
const error = ref(false);
const props = defineProps({
title: {
type: String,
required: true,
default: () => '',
validator: (items) => {
return items;
},
},
devices: {
type: Array,
required: true,
default: () => [],
validator: (items) => {
const validItems = items.filter((item) => item.icon === 'camera');
return validItems.every((item) => {
return (
typeof item === 'object' &&
item !== null &&
typeof item.id === 'number' &&
typeof item.name === 'string' &&
typeof item.icon === 'string' &&
typeof item.detail === 'string' &&
(!item.status || typeof item.status === 'number')
);
});
},
},
});
const emit = defineEmits(['changeDevice']);
// 显示天气详情弹窗
const showWeatherDetail = (data) => {
emit('changeDevice', { message: data });
};
// 监听 currentDevice 的变化
watch(currentDevice, (newValue, oldValue) => {
showWeatherDetail(newValue);
// console.log(`count 从 ${oldValue} 变为 ${newValue}`);
});
onUnmounted(() => {
if (hls.value) {
hls.value.destroy();
}
});
onMounted(async () => {
if (Hls.isSupported()) {
hls.value = new Hls();
hls.value.loadSource('https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8');
hls.value.attachMedia(videoPlayer.value);
hls.value.on(Hls.Events.MANIFEST_PARSED, () => {
videoPlayer.value.play();
});
} else if (videoPlayer.value.canPlayType('application/vnd.apple.mpegurl')) {
// Safari原生支持HLS
videoPlayer.value.src = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
}
});
</script>
<template>
<el-card style="border-radius: 16px">
<div style="display: flex; justify-content: space-between">
<div style="font-size: 16px; font-weight: bold; text-align: left">{{ title }}</div>
<div>
<div>当前设备状态</div>
<div>
<div class="dot"></div>
<span>正常</span>
</div>
</div>
<div style="color: #999999; line-height: 25px">
当前设备
<el-select v-model="currentDevice" placeholder="Select" size="small" style="width: 160px; margin-left: 10px">
<el-option v-for="item in devices" :key="item.value" :label="item.detail" :value="item.id" />
</el-select>
</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: center">
<div class="video-wrapper">
<video ref="videoPlayer" controls autoplay muted></video>
<div v-if="loading" class="status-message">正在加载直播流...</div>
<div v-if="error" class="status-message error">{{ error }}</div>
</div>
<div class="pictures-wrapper">
<img :src="getAssetsFile('images/smartFarm/goUp.png')" alt="" style="width: 100px" />
<img :src="getAssetsFile('images/smartFarm/testPic1.png')" style="width: 80%; margin: 5px 0" :alt="devices[currentDevice].detail" />
<img :src="getAssetsFile('images/smartFarm/testPic1.png')" style="width: 80%; margin: 5px 0" :alt="devices[currentDevice].detail" />
<img :src="getAssetsFile('images/smartFarm/goDown.png')" alt="" style="width: 100px" />
</div>
</div>
</el-card>
</template>
<style scoped lang="scss">
.video-wrapper {
height: 100%;
margin-top: 30px;
width: 58%;
video {
width: 100%;
border-radius: 16px;
}
}
.pictures-wrapper {
width: 38%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
margin-top: 20px;
img {
cursor: pointer;
}
}
.dot {
height: 10px;
width: 10px;
display: inline-block;
border-radius: 90px;
background-color: #25bf82;
}
</style>