|
|
@ -1,76 +1,34 @@ |
|
|
|
<template> |
|
|
|
|
|
|
|
<div id="videoWrapper"> |
|
|
|
<div id="windowVideoPlayer" ></div> |
|
|
|
|
|
|
|
<CameraLeftMenu></CameraLeftMenu> |
|
|
|
<div id="videoWrapper" :style="`height: 300px;`"> |
|
|
|
<Draggable></Draggable> |
|
|
|
<BorderOutlined class="enlarge" @click="clickEnlarge" /> |
|
|
|
<div id="windowVideoPlayer"></div> |
|
|
|
<!-- 云台控制 --> |
|
|
|
<VideoControlSimple></VideoControlSimple> |
|
|
|
<!-- <VideoControlSimple></VideoControlSimple> --> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script setup lang='ts'> |
|
|
|
////@ts-nocheck |
|
|
|
import { ref, h, onMounted, getCurrentInstance, ComponentInternalInstance, onUnmounted, watch } from "vue"; |
|
|
|
import * as markSearchApi from '@/axios/core/markSearchApi'; |
|
|
|
import Draggable from '@/components/Draggable.vue'; |
|
|
|
import { BorderOutlined } from '@ant-design/icons-vue'; |
|
|
|
import { useStore } from '@/store/index'; |
|
|
|
import { apiUrl } from "@/axios"; |
|
|
|
import { storeToRefs } from 'pinia'; |
|
|
|
import Msg from "@/utils/message"; |
|
|
|
import CameraLeftMenu from '@/views/page/Aside/cameraLeftMenu.vue' |
|
|
|
import VideoControlSimple from './VideoControl/VideoControlSimple.vue'; |
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
|
|
|
let piniaStore = useStore(); |
|
|
|
let player = <HTMLVideoElement>document.querySelector('#windowVideoPlayer') |
|
|
|
let canvasWidth = ref(0) |
|
|
|
let canvasHeight = ref(0) |
|
|
|
let curSelectKey = storeToRefs(piniaStore).curSelectKey |
|
|
|
let closeVideoKey = storeToRefs(piniaStore).closeVideoKey |
|
|
|
let cameraMap = storeToRefs(piniaStore).cameraMap |
|
|
|
let isActiveChoose = ref(false) |
|
|
|
let labelList = ref<any[]>([]) |
|
|
|
let addLabel = storeToRefs(piniaStore).addLabel |
|
|
|
let addLabelLeft = ref(0); |
|
|
|
let addLabelTop = ref(0); |
|
|
|
const isEnlarge=ref(false); |
|
|
|
var jessibuca = ref(); |
|
|
|
const curVideoKey = ref() |
|
|
|
onMounted(() => { |
|
|
|
{ |
|
|
|
player = <HTMLVideoElement>document.querySelector('#windowVideoPlayer'); |
|
|
|
loadVideoCanvas(); |
|
|
|
changeVideoCanvasSize(); |
|
|
|
create() |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
watch(curSelectKey, (newVal, oldVal) => { |
|
|
|
switchCamera(newVal) |
|
|
|
}) |
|
|
|
watch(closeVideoKey, (newVal, oldVal) => { |
|
|
|
if (curVideoKey.value == newVal) { |
|
|
|
destroyVideo() |
|
|
|
piniaStore.updateCloseVideoKey("") |
|
|
|
piniaStore.updateCurSelectKey("") |
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
watch(addLabel, (newVal, oldVal) => { |
|
|
|
if (newVal.isAddLabel) { |
|
|
|
isActiveChoose.value = true |
|
|
|
document.body.onmousemove = (e) => { |
|
|
|
addLabelTop.value = e.clientY |
|
|
|
addLabelLeft.value = e.clientX |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
function destroyVideo() { |
|
|
|
jessibuca.value.destroy(); |
|
|
|
create() |
|
|
|
labelList.value = [] |
|
|
|
} |
|
|
|
//创建流媒体 |
|
|
|
function create() { |
|
|
|
var showOperateBtns = false; // 是否显示按钮 |
|
|
@ -78,12 +36,12 @@ function create() { |
|
|
|
|
|
|
|
jessibuca.value = new Jessibuca({ |
|
|
|
container: player, |
|
|
|
videoBuffer: 0.5, // 缓存时长 |
|
|
|
videoBuffer: 0.2, // 缓存时长 |
|
|
|
isResize: false, |
|
|
|
text: "", |
|
|
|
loadingText: "", |
|
|
|
useMSE: false, |
|
|
|
debug: true, |
|
|
|
debug: false, |
|
|
|
showBandwidth: showOperateBtns, // 显示网速 |
|
|
|
operateBtns: { |
|
|
|
fullscreen: showOperateBtns, |
|
|
@ -105,60 +63,14 @@ function create() { |
|
|
|
jessibuca.value.play("ws://192.168.1.117:8080/jessica/live/test.flv") |
|
|
|
} |
|
|
|
|
|
|
|
function clickEnlarge() { |
|
|
|
|
|
|
|
function loadVideoCanvas() { |
|
|
|
window.addEventListener('resize', () => { |
|
|
|
changeVideoCanvasSize(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function changeVideoCanvasSize() { |
|
|
|
canvasWidth.value = player.clientWidth; |
|
|
|
canvasHeight.value = player.clientHeight; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function switchCamera(cameraId: string) { |
|
|
|
console.log('camera switch.', cameraId, typeof cameraId); |
|
|
|
|
|
|
|
// step1, get camera obj. |
|
|
|
console.log('get camera obj.', cameraMap.value); |
|
|
|
let cameraObj = cameraMap.value.get(cameraId); |
|
|
|
console.log(cameraObj, 'cameraObj'); |
|
|
|
|
|
|
|
if (!cameraObj) { |
|
|
|
console.log('camera obj not found.'); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
destroyVideo() |
|
|
|
console.log('connect webrtc-steamer.'); |
|
|
|
jessibuca.value.play("ws://192.168.1.117:8080/jessica/live/test.flv") |
|
|
|
curVideoKey.value = cameraId |
|
|
|
// step4, active camera searcher. |
|
|
|
markSearchApi.IsExistsSearcher({ |
|
|
|
'cameraId': cameraObj.id |
|
|
|
}).then((res: any) => { |
|
|
|
let flag: boolean = res.data.data; |
|
|
|
if (!flag) { |
|
|
|
console.log('not exist searcher.'); |
|
|
|
markSearchApi.ActiveSearcher({ |
|
|
|
'cameraId': cameraObj.id |
|
|
|
}).then((res: any) => { |
|
|
|
let flag: boolean = res.data.data; |
|
|
|
console.log('activate searcher : ', flag); |
|
|
|
if (flag) { |
|
|
|
console.log('load camera labels'); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
console.log('load camera labels'); |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
// step5, load camera labels. |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//刷新页面 |
|
|
@ -174,10 +86,20 @@ onUnmounted(() => { |
|
|
|
|
|
|
|
<style scoped lang='less'> |
|
|
|
#videoWrapper { |
|
|
|
// height: 100vh; |
|
|
|
width: 100%; |
|
|
|
position: relative; |
|
|
|
overflow: hidden; |
|
|
|
// overflow: hidden; |
|
|
|
|
|
|
|
.enlarge { |
|
|
|
position: absolute; |
|
|
|
z-index: 3; |
|
|
|
top: -26px; |
|
|
|
right: 40px; |
|
|
|
transform: translate(-50%, -50%); |
|
|
|
cursor: pointer; |
|
|
|
font-size: 14px; |
|
|
|
color: "#fff", |
|
|
|
} |
|
|
|
|
|
|
|
#windowVideoPlayer { |
|
|
|
height: 100%; |
|
|
@ -186,47 +108,6 @@ onUnmounted(() => { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.labels { |
|
|
|
position: absolute; |
|
|
|
top: 0; |
|
|
|
left: 0; |
|
|
|
z-index: 2; |
|
|
|
|
|
|
|
.labels-item { |
|
|
|
position: relative; |
|
|
|
cursor: pointer; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
align-items: center; |
|
|
|
|
|
|
|
>div { |
|
|
|
position: relative; |
|
|
|
} |
|
|
|
|
|
|
|
.label-content { |
|
|
|
position: absolute; |
|
|
|
top: 50%; |
|
|
|
left: 50%; |
|
|
|
transform: translate(-50%, -55%); |
|
|
|
} |
|
|
|
|
|
|
|
img { |
|
|
|
width: 120px; |
|
|
|
height: 50px; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.lavels-video { |
|
|
|
position: fixed; |
|
|
|
transform: translate(-50%, -100%); |
|
|
|
} |
|
|
|
|
|
|
|
.lavels-build { |
|
|
|
|
|
|
|
transform: translate(-10px, -10px); |
|
|
|
position: fixed; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
@ -234,3 +115,11 @@ onUnmounted(() => { |
|
|
|
color: #000 !important; |
|
|
|
} |
|
|
|
</style> |
|
|
|
<style> |
|
|
|
.ant-notification-notice { |
|
|
|
margin-bottom: 0 !important; |
|
|
|
padding-left: 0 !important; |
|
|
|
padding-right: 0 !important; |
|
|
|
padding-bottom: 0 !important; |
|
|
|
} |
|
|
|
</style> |
|
|
|