4 changed files with 437 additions and 7 deletions
@ -0,0 +1,430 @@ |
|||||
|
<!-- |
||||
|
*@描述: 云台控制 |
||||
|
*@作者: |
||||
|
*@日期: |
||||
|
*@版本:1.0 |
||||
|
*/ |
||||
|
--> |
||||
|
<template> |
||||
|
<div> |
||||
|
<div class="camera-control"> |
||||
|
<div class="camera-operate"> |
||||
|
<div class="camera-direct"> |
||||
|
|
||||
|
<!--上--> |
||||
|
<div class="upButton" style="background-position:-30px 0" @mousedown="upStart()" @mouseup="stopMove()"> |
||||
|
</div> |
||||
|
|
||||
|
<!--左--> |
||||
|
<div class="leftButton" style="background-position:0 -30px" @mousedown="leftStart()" @mouseup="stopMove()"> |
||||
|
</div> |
||||
|
|
||||
|
<!--右--> |
||||
|
<div class="rightButton" style="background-position:-60px -30px" @mousedown="rightStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
|
||||
|
<!--下--> |
||||
|
<div class="downButton" style="background-position:-30px -60px" @mousedown="downStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
<!-- <div class="camera-function"> |
||||
|
<div class="function-box"> |
||||
|
<div class="function-item" |
||||
|
style="background-position:-128px 0;border-right: 1px rgba(179, 177, 177, 0.97) dotted;" |
||||
|
@mousedown="zoomIn()" @mouseup="stopMove()" title="变倍+"> |
||||
|
</div> |
||||
|
<div class="function-item" style="background-position:-92px 0;" @mousedown="zoomOut()" @mouseup="stopMove()" |
||||
|
title="变倍-"> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
<!-- <div class="function-box"> |
||||
|
<div class="function-item" |
||||
|
style="background-position:-128px -30px;border-right:1px rgba(179, 177, 177, 0.97) dotted; " |
||||
|
@mousedown="focusIn()" @mouseup="focusStop()" title="变焦+"> |
||||
|
</div> |
||||
|
<div class="function-item" style="background-position:-92px -30px;" @mousedown="focusOut()" |
||||
|
@mouseup="focusStop()" title="变焦-"> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
<!-- <div class="function-box"> |
||||
|
<div class="function-item" |
||||
|
style="background-position:-202px 0; border-right:1px rgba(179, 177, 177, 0.97) dotted;" |
||||
|
@mousedown="handleScreenSnap()" title="抓拍"> |
||||
|
</div> |
||||
|
<div class="function-item" style="background-position:-162px -89px;" @mousedown="openImgListDialog()" |
||||
|
title="抓拍列表"> |
||||
|
</div> |
||||
|
</div> --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { axios } from '@/utils/axios'; |
||||
|
import Qs from 'qs' |
||||
|
import { apiUrl } from "@/axios"; |
||||
|
import { onBeforeUnmount, onMounted, ref } from 'vue'; |
||||
|
|
||||
|
const ip = ref('337342439297349') |
||||
|
const onvifUrl = ref(apiUrl.OnvifApiUrl) |
||||
|
const currentStep = ref(5); |
||||
|
const autoFlag = ref(false) |
||||
|
const screenSnapList: any = ref({ |
||||
|
title: '抓拍列表', |
||||
|
visible: false |
||||
|
}) |
||||
|
const url: any = ref({ |
||||
|
isExist: '/onvif/isExists', |
||||
|
add: '/onvif/register', |
||||
|
ptzMove: '/onvif/continuousMove', |
||||
|
ptzStopMove: '/onvif/stopMove', |
||||
|
focusMove: '/onvif/focusContinuousMove', |
||||
|
focusStopMove: '/onvif/focusStopMove', |
||||
|
getSnapshot: '/onvif/getSnapshotUrl', |
||||
|
// screenSnap: 'camera/setting/screenSnap', |
||||
|
delete: '/onvif/delete' |
||||
|
}) |
||||
|
|
||||
|
onMounted(() => { |
||||
|
checkExistOnvif(); |
||||
|
}) |
||||
|
onBeforeUnmount(() => { |
||||
|
//注销 |
||||
|
onvifOperateHandler(url.value.delete, 'post', { cameraId: ip.value }) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
//发送指令 |
||||
|
function onvifOperateHandler(url: any, method: any, params: any, callback: any = {}) { |
||||
|
url = onvifUrl.value + url |
||||
|
let reqParams = { url: url, method: method } |
||||
|
let dataParam = (method === 'get') ? { params: params } : { data: Qs.stringify(params) } |
||||
|
Object.assign(reqParams, dataParam); |
||||
|
// console.log("reqParams",reqParams); |
||||
|
axios(reqParams).then((res: any) => { |
||||
|
// console.log(res); |
||||
|
if (res.status == 200) { |
||||
|
if (!res.Errors) { |
||||
|
// console.log("成功"); |
||||
|
if (callback && typeof callback === 'function') { |
||||
|
callback(res) |
||||
|
} |
||||
|
} else { |
||||
|
// callUtil.$emit('openNotification', res.Errors, 2, 'warning', '50px') |
||||
|
} |
||||
|
} else { |
||||
|
// callUtil.$emit('openNotification', '云台控制异常', 2, 'error', '50px') |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//检查是否已经注册 |
||||
|
function checkExistOnvif() { |
||||
|
// Check onvif server is exists, if not exists , add it |
||||
|
let params = { cameraId: ip.value } |
||||
|
onvifOperateHandler(url.value.isExist, 'get', params, (res: any) => { |
||||
|
console.log(res); |
||||
|
if (!res.isSuccess || res.data !== true) { |
||||
|
console.log("不存在,请先注册"); |
||||
|
onvifOperateHandler(url.value.add, 'post', params, (res: any) => { |
||||
|
console.log("注册信息", res); |
||||
|
console.log("注册成功"); |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//指令类型 |
||||
|
function createPtzParam(instruct: any, step: any) { |
||||
|
let ptzParam |
||||
|
let speed = 0.1 * step |
||||
|
switch (instruct) { |
||||
|
case 'up': |
||||
|
ptzParam = new Float32Array([0, 1, 0]) |
||||
|
break |
||||
|
case 'leftUp': |
||||
|
ptzParam = new Float32Array([-1, 1, 0]) |
||||
|
break |
||||
|
case 'rightUp': |
||||
|
ptzParam = new Float32Array([1, 1, 0]) |
||||
|
break |
||||
|
case 'down': |
||||
|
ptzParam = new Float32Array([0, -1, 0]) |
||||
|
break |
||||
|
case 'leftDown': |
||||
|
ptzParam = new Float32Array([-1, -1, 0]) |
||||
|
break |
||||
|
case 'rightDown': |
||||
|
ptzParam = new Float32Array([1, -1, 0]) |
||||
|
break |
||||
|
case 'left': |
||||
|
ptzParam = new Float32Array([-1, 0, 0]) |
||||
|
break |
||||
|
case 'right': |
||||
|
ptzParam = new Float32Array([1, 0, 0]) |
||||
|
break |
||||
|
case 'zoomIn': |
||||
|
ptzParam = new Float32Array([0, 0, 1]) |
||||
|
break |
||||
|
case 'zoomOut': |
||||
|
ptzParam = new Float32Array([0, 0, -1]) |
||||
|
break |
||||
|
default: |
||||
|
ptzParam = new Float32Array([0, 0, 0]) |
||||
|
} |
||||
|
return { pan: ptzParam[0] * speed, tilt: ptzParam[1] * speed, zoom: ptzParam[2] * speed } |
||||
|
} |
||||
|
|
||||
|
//停止移动 |
||||
|
function stopMove() { |
||||
|
let params = { cameraId: ip.value } |
||||
|
onvifOperateHandler(url.value.ptzStopMove, 'post', params) |
||||
|
} |
||||
|
|
||||
|
//上 |
||||
|
function upStart() { |
||||
|
let instruct = 'up' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
// console.log("上", params); |
||||
|
} |
||||
|
|
||||
|
//下 |
||||
|
function downStart() { |
||||
|
let instruct = 'down' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
console.log("下", params); |
||||
|
} |
||||
|
|
||||
|
//左 |
||||
|
function leftStart() { |
||||
|
let instruct = 'left' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
} |
||||
|
//右 |
||||
|
function rightStart() { |
||||
|
let instruct = 'right' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
} |
||||
|
|
||||
|
//变倍+ |
||||
|
function zoomIn() { |
||||
|
let instruct = 'zoomIn' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
} |
||||
|
//变倍- |
||||
|
function zoomOut() { |
||||
|
let instruct = 'zoomOut' |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
let ptzParams = createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
onvifOperateHandler(url.value.ptzMove, 'post', params) |
||||
|
} |
||||
|
|
||||
|
//变焦+ |
||||
|
function focusIn() { |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
Object.assign(params, { speed: (0.1 * step) }) |
||||
|
onvifOperateHandler(url.value.focusMove, 'post', params) |
||||
|
} |
||||
|
//变焦- |
||||
|
function focusOut() { |
||||
|
let step = currentStep.value |
||||
|
let params = { cameraId: ip.value } |
||||
|
Object.assign(params, { speed: (-0.1 * step) }) |
||||
|
onvifOperateHandler(url.value.focusMove, 'post', params) |
||||
|
} |
||||
|
//停止变焦 |
||||
|
function focusStop() { |
||||
|
onvifOperateHandler(url.value.focusStopMove, 'post', { cameraId: ip.value }) |
||||
|
} |
||||
|
|
||||
|
//抓拍 |
||||
|
function handleScreenSnap(){ |
||||
|
|
||||
|
} |
||||
|
function openImgListDialog(){ |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="less"> |
||||
|
.camera-control { |
||||
|
/* color: #080000; */ |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-operate { |
||||
|
display: -webkit-flex; |
||||
|
/* Safari */ |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
.camera-control .camera-direct { |
||||
|
display: -webkit-flex; |
||||
|
/* Safari */ |
||||
|
width: 110px; |
||||
|
height: 100px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
flex-wrap: wrap; |
||||
|
padding: 10px 10px 0 0; |
||||
|
/*margin: auto;*/ |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-direct .direct-item { |
||||
|
width: 30px; |
||||
|
height: 30px; |
||||
|
background-repeat: no-repeat; |
||||
|
background-size: 400px 300px; |
||||
|
background-image: url('@/assets/images/ptzIcons/ptz-icons.png'); |
||||
|
margin: 1px 1px 1px 1px; |
||||
|
border: 1px rgba(190, 188, 188, 0.97) solid; |
||||
|
border-radius: 1px; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-direct .direct-item:hover { |
||||
|
background-color: rgba(208, 212, 208, 0.3); |
||||
|
background-image: url('@/assets/images/ptzIcons/ptz-icons-on.png'); |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-direct .direct-item .img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-function { |
||||
|
display: -webkit-flex; |
||||
|
/* Safari */ |
||||
|
/*margin-left: 20px;*/ |
||||
|
margin-left: 10px; |
||||
|
width: 90px; |
||||
|
height: 120px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
flex-wrap: wrap; |
||||
|
padding: 10px 0 0 10px; |
||||
|
/*margin: auto;*/ |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-function .function-box { |
||||
|
display: -webkit-flex; |
||||
|
/* Safari */ |
||||
|
height: 30px; |
||||
|
width: 65px; |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
border: 1px rgba(190, 188, 188, 0.97) solid; |
||||
|
border-radius: 1px; |
||||
|
margin: 1px 1px 1px 1px; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-function .function-item { |
||||
|
width: 32px; |
||||
|
height: 29px; |
||||
|
background-repeat: no-repeat; |
||||
|
background-size: 400px 300px; |
||||
|
|
||||
|
background-image: url('@/assets/images/ptzIcons/ptz-icons.png'); |
||||
|
/*border: 1px rgba(179, 177, 177, 0.64) solid;*/ |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-function .function-item:hover { |
||||
|
background-color: rgba(208, 212, 208, 0.3); |
||||
|
background-image: url('@/assets/images/ptzIcons/ptz-icons-on.png'); |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-function .function-item .img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
/* 滑动输入条 */ |
||||
|
input[type='range'] { |
||||
|
display: block; |
||||
|
-webkit-appearance: none; |
||||
|
background-color: #bdc3c7; |
||||
|
width: 100%; |
||||
|
height: 5px; |
||||
|
margin: 6% auto; |
||||
|
} |
||||
|
|
||||
|
input[type='range']::-webkit-slider-thumb { |
||||
|
-webkit-appearance: none; |
||||
|
height: 20px; |
||||
|
width: 20px; |
||||
|
margin-top: -5px; |
||||
|
/*使滑块超出轨道部分的偏移量相等*/ |
||||
|
background: #ffffff; |
||||
|
border-radius: 50%; |
||||
|
/*外观设置为圆形*/ |
||||
|
border: solid 0.125em rgba(205, 224, 230, 0.5); |
||||
|
/*设置边框*/ |
||||
|
box-shadow: 0 0.125em 0.125em #3b4547; |
||||
|
/*添加底部阴影*/ |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
input[type='range']::-webkit-slider-runnable-track { |
||||
|
height: 10px; |
||||
|
border-radius: 10px; |
||||
|
/*将轨道设为圆角的*/ |
||||
|
box-shadow: 0 1px 1px #def3f8, inset 0 0.125em 0.125em #0d1112; |
||||
|
/*轨道内置阴影效果*/ |
||||
|
} |
||||
|
|
||||
|
input[type='range']:focus { |
||||
|
outline: none; |
||||
|
} |
||||
|
|
||||
|
input[type='range']::-webkit-slider-thumb:hover { |
||||
|
border: 5px solid #b00303; |
||||
|
} |
||||
|
|
||||
|
input[type='range']::-webkit-slider-thumb:active { |
||||
|
transform: scale(1.2); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.upButton{ |
||||
|
width: 100%; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
</style> |
Loading…
Reference in new issue