116 lines
3.4 KiB
Vue
116 lines
3.4 KiB
Vue
<script setup>
|
|
import { ref, reactive, onMounted, onUnmounted } 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) => {
|
|
return items.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')
|
|
);
|
|
});
|
|
},
|
|
},
|
|
});
|
|
|
|
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 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;
|
|
}
|
|
}
|
|
</style>
|