|
@@ -0,0 +1,113 @@
|
|
|
+<template>
|
|
|
+ <Dialog :title="dialogTitle +'(' + memo + ')'" v-model="dialogVisible" destroy-on-close @close="close">
|
|
|
+ <ContentWrap>
|
|
|
+ <video
|
|
|
+ ref="videoPlayer"
|
|
|
+ controls="true" autoplay="true"
|
|
|
+ ></video>
|
|
|
+ </ContentWrap>
|
|
|
+ <b>{{memo}}地址:</b> {{playUrl}}
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="play('res')"><Icon icon="fa-solid:video" /> 原画面</el-button>
|
|
|
+ <el-button type="success" @click="play('ai')"><Icon icon="fa-solid:video" /> AI画面</el-button>
|
|
|
+ <el-button @click="close"><Icon icon="ep:close" /> 关 闭</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+</template>
|
|
|
+<script setup lang="ts">
|
|
|
+import { CameraApi } from '@/api/safe/camera'
|
|
|
+import { ServerApi } from '@/api/safe/server'
|
|
|
+import { onUnmounted} from 'vue'
|
|
|
+
|
|
|
+defineOptions({ name: 'CameraView' })
|
|
|
+
|
|
|
+const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
+const dialogTitle = ref('') // 弹窗的标题
|
|
|
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
|
+const videoPlayer = ref(null)
|
|
|
+let sdk = null
|
|
|
+let memo = ref('')
|
|
|
+let playUrl = ref('')
|
|
|
+let webrtcUrl = ref('')
|
|
|
+let webrtcAiUrl = ref('')
|
|
|
+
|
|
|
+/** 打开弹窗 */
|
|
|
+const open = async (id: number) => {
|
|
|
+ dialogVisible.value = true
|
|
|
+ if (id) {
|
|
|
+ formLoading.value = true
|
|
|
+ try {
|
|
|
+ const camera = await CameraApi.getCamera(id)
|
|
|
+ if(camera && camera.serverId){
|
|
|
+ const server = await ServerApi.getServer(camera.serverId);
|
|
|
+ dialogTitle.value = server.name + ' - ' + camera.name + ' 监视预览'
|
|
|
+ webrtcUrl.value = 'http://' + server.ip + ':1985/rtc/v1/whep/?app=' + server.domain + '&stream=' + camera.code
|
|
|
+ webrtcAiUrl.value = webrtcUrl.value + '-ai'
|
|
|
+ play('res')
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ formLoading.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const play = async (type: String) => {
|
|
|
+ try {
|
|
|
+ if(type === 'res'){
|
|
|
+ playUrl.value = webrtcUrl.value
|
|
|
+ memo.value = '原画面'
|
|
|
+ }else if(type === 'ai'){
|
|
|
+ playUrl.value = webrtcAiUrl.value
|
|
|
+ memo.value = 'AI画面'
|
|
|
+ }
|
|
|
+ console.log('播放地址:' + playUrl.value)
|
|
|
+ if (playUrl.value) {
|
|
|
+ if (sdk) {
|
|
|
+ sdk.close()
|
|
|
+ sdk = null
|
|
|
+ }
|
|
|
+ sdk = new SrsRtcWhipWhepAsync()
|
|
|
+ sdk.play(playUrl.value)
|
|
|
+ .then(function (session) {
|
|
|
+ videoPlayer.value.srcObject = sdk.stream
|
|
|
+ })
|
|
|
+ .catch(function (reason) {
|
|
|
+ console.error(reason)
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ ElMessage.error(
|
|
|
+ playUrl.value + '视频源无法播放'
|
|
|
+ )
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const close = async () => {
|
|
|
+ if(dialogVisible){
|
|
|
+ dialogVisible.value = false
|
|
|
+ }
|
|
|
+ if (sdk) {
|
|
|
+ sdk.close()
|
|
|
+ }
|
|
|
+ sdk = null
|
|
|
+ playUrl = ref('')
|
|
|
+ memo = ref('')
|
|
|
+}
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ close
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+defineExpose({ open}) // 暴漏 open 方法,用于打开弹窗
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+video {
|
|
|
+ width: 100%;
|
|
|
+ height: auto;
|
|
|
+}
|
|
|
+</style>
|