8 changed files with 2411 additions and 1232 deletions
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 65 KiB |
@ -1,6 +1,6 @@ |
|||||
export const apiUrl = { |
export const apiUrl = { |
||||
CisApiUrl: 'http://192.168.1.119:800/api', |
CisApiUrl: 'http://192.168.1.119:800/api', |
||||
WebRtcUrl: 'http://192.168.1.119:8000', |
WebRtcUrl: 'http://192.168.1.119:8000', |
||||
OnvifApiUrl: '' |
OnvifApiUrl: 'http://192.168.1.119:800/api' |
||||
// CisApiUrl: 'https://192.168.1.119:5001/api'
|
// CisApiUrl: 'https://192.168.1.119:5001/api'
|
||||
} |
} |
||||
|
@ -0,0 +1,559 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="camera-control"> |
||||
|
<div class="camera-control-title"> |
||||
|
云台 |
||||
|
</div> |
||||
|
<hr style="background-color: #e2e2e2; height: 1px; border: 0;" /> |
||||
|
<div class="camera-operate"> |
||||
|
<div class="camera-direct"> |
||||
|
<!--左上--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:0 0" |
||||
|
@mousedown="leftUpStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--上--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-30px 0" |
||||
|
@mousedown="upStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--右上--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-60px 0" |
||||
|
@mousedown="rightUpStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--左--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:0 -30px" |
||||
|
@mousedown="leftStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--自动--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-30px -30px" |
||||
|
@click="autoStart()"> |
||||
|
</div> |
||||
|
<!--右--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-60px -30px" |
||||
|
@mousedown="rightStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--左下--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:0 -60px" |
||||
|
@mousedown="leftDownStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--下--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-30px -60px" |
||||
|
@mousedown="downStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--右下--> |
||||
|
<div class="direct-item" |
||||
|
style="background-position:-60px -60px" |
||||
|
@mousedown="rightDownStart()" |
||||
|
@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> |
||||
|
<a-row> |
||||
|
<a-col span="1"></a-col> |
||||
|
<a-col span="19"> |
||||
|
<label class="demonstration">云台速度:{{ currentStep }}</label> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row type="flex"> |
||||
|
<a-col span="2"></a-col> |
||||
|
<a-col span="19"> |
||||
|
<input type="range" |
||||
|
min="1" |
||||
|
max="10" |
||||
|
step="1" |
||||
|
v-model="currentStep" /> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
</div> |
||||
|
<!-- 图片列表弹窗 --> |
||||
|
<!-- <img-list-dialog :visible.sync="screenSnapList.visible" |
||||
|
:camera-id="videoInfo.cameraId" |
||||
|
:title="screenSnapList.title" /> --> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// import callUtil from '@/utils/callUtil' |
||||
|
// import ImgListDialog from '@/components/earthMap/ImgListDialog' |
||||
|
// import { axios } from '@/utils/request' |
||||
|
// import axios from "axios"; |
||||
|
import {axios} from '@/utils/axios'; |
||||
|
import Qs from 'qs' |
||||
|
import * as onvifApi from '@/axios/onvif/onvifApi'; |
||||
|
import {apiUrl} from "@/axios"; |
||||
|
// import { postAction } from '@api/manage' |
||||
|
|
||||
|
export default { |
||||
|
name: 'VideoControl', |
||||
|
props: ['id', 'name', 'width', 'height', |
||||
|
// 'ip', |
||||
|
'user', |
||||
|
'password'], |
||||
|
components: { |
||||
|
// ImgListDialog |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
// onvifUrl: window._CONFIG['onvifURL'], |
||||
|
// onvifUrl: "http://192.168.1.119:800/api", |
||||
|
ip: '337342439297349',//测试球机 |
||||
|
onvifUrl: apiUrl.OnvifApiUrl, |
||||
|
currentStep: 5, |
||||
|
autoFlag: false, |
||||
|
screenSnapList: { |
||||
|
title: '抓拍列表', |
||||
|
visible: false |
||||
|
}, |
||||
|
videoInfo: { |
||||
|
cameraId: this.id, |
||||
|
cameraName: this.name, |
||||
|
cameraIP: this.ip, |
||||
|
cameraUser: this.user, |
||||
|
cameraPassword: this.password, |
||||
|
instruct: this.instruct, |
||||
|
step: 0 |
||||
|
}, |
||||
|
url: { |
||||
|
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' |
||||
|
}, |
||||
|
visible: false |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.checkExistOnvif() |
||||
|
}, |
||||
|
beforeUnmount(){ |
||||
|
//注销 |
||||
|
let params = { cameraId: this.ip } |
||||
|
this.onvifOperateHandler(this.url.delete, 'post', params) |
||||
|
}, |
||||
|
methods: { |
||||
|
onvifOperateHandler(url, method, params, callback) { |
||||
|
url = this.onvifUrl + 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) => { |
||||
|
// 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') |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
checkExistOnvif() { |
||||
|
// Check onvif server is exists, if not exists , add it |
||||
|
let params = { cameraId: this.ip } |
||||
|
this.onvifOperateHandler(this.url.isExist, 'get', params, (res) => { |
||||
|
console.log(res); |
||||
|
if (!res.isSuccess || res.data !== true) { |
||||
|
console.log("不存在,请先注册"); |
||||
|
Object.assign(params, { username: this.videoInfo.cameraUser, password: this.videoInfo.cameraPassword }) |
||||
|
this.onvifOperateHandler(this.url.add, 'post', params, (res) => { |
||||
|
console.log("注册信息",res); |
||||
|
console.log("注册成功"); |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
createPtzParam(instruct, step) { |
||||
|
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 } |
||||
|
}, |
||||
|
upStart() { |
||||
|
|
||||
|
let instruct = 'up' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
console.log("上",params); |
||||
|
}, |
||||
|
leftUpStart() { |
||||
|
let instruct = 'leftUp' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
rightUpStart() { |
||||
|
let instruct = 'rightUp' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
downStart() { |
||||
|
let instruct = 'down' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
console.log("下",params); |
||||
|
}, |
||||
|
leftDownStart() { |
||||
|
let instruct = 'leftDown' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
rightDownStart() { |
||||
|
let instruct = 'rightDown' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
leftStart() { |
||||
|
let instruct = 'left' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
rightStart() { |
||||
|
let instruct = 'right' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
zoomIn() { |
||||
|
let instruct = 'zoomIn' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
zoomOut() { |
||||
|
let instruct = 'zoomOut' |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
let ptzParams = this.createPtzParam(instruct, step) |
||||
|
Object.assign(params, ptzParams) |
||||
|
this.onvifOperateHandler(this.url.ptzMove, 'post', params) |
||||
|
}, |
||||
|
autoStart() { |
||||
|
if (this.autoFlag) { |
||||
|
this.stopMove() |
||||
|
this.autoFlag = false |
||||
|
} else { |
||||
|
this.leftStart() |
||||
|
this.autoFlag = true |
||||
|
} |
||||
|
}, |
||||
|
stopMove() { |
||||
|
let params = { cameraId: this.ip } |
||||
|
this.onvifOperateHandler(this.url.ptzStopMove, 'post', params) |
||||
|
}, |
||||
|
focusIn() { |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
Object.assign(params, { speed: (0.1 * step) }) |
||||
|
this.onvifOperateHandler(this.url.focusMove, 'post', params) |
||||
|
}, |
||||
|
focusOut() { |
||||
|
let step = this.currentStep |
||||
|
let params = { cameraId: this.ip } |
||||
|
Object.assign(params, { speed: (-0.1 * step) }) |
||||
|
this.onvifOperateHandler(this.url.focusMove, 'post', params) |
||||
|
}, |
||||
|
focusStop() { |
||||
|
let params = { cameraId: this.ip } |
||||
|
this.onvifOperateHandler(this.url.focusStopMove, 'post', params) |
||||
|
}, |
||||
|
handleScreenSnap() { |
||||
|
let params = { cameraId: this.ip } |
||||
|
this.onvifOperateHandler(this.url.getSnapshot, 'get', params, (res) => { |
||||
|
let snapshotUrl = res.data |
||||
|
let newInfo = { snapshotUrl: snapshotUrl } |
||||
|
Object.assign(newInfo, this.videoInfo) |
||||
|
postAction(this.url.screenSnap, newInfo).then(() => { |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
openImgListDialog() { |
||||
|
this.screenSnapList.visible = true |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.camera-control { |
||||
|
color: #080000; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__bar { |
||||
|
background-color: #b00303; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__button { |
||||
|
border: 2px solid #848486; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__runway { |
||||
|
width: 92%; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-operate { |
||||
|
display: -webkit-flex; /* Safari */ |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-speed { |
||||
|
padding-top: 20px; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-speed input { |
||||
|
width: 40px; |
||||
|
color: black; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-title { |
||||
|
padding-top: 7px; |
||||
|
text-align: center; |
||||
|
height: 35px; |
||||
|
line-height: 28px; |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.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); |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,526 @@ |
|||||
|
<!-- |
||||
|
*@描述: 云台控制 |
||||
|
*@作者: |
||||
|
*@日期: |
||||
|
*@版本:1.0 |
||||
|
*/ |
||||
|
--> |
||||
|
<template> |
||||
|
<div> |
||||
|
<div class="camera-control"> |
||||
|
<div class="camera-control-title"> |
||||
|
云台 |
||||
|
</div> |
||||
|
<hr style="background-color: #e2e2e2; height: 1px; border: 0;" /> |
||||
|
<div class="camera-operate"> |
||||
|
<div class="camera-direct"> |
||||
|
<!--左上--> |
||||
|
<div class="direct-item" style="background-position:0 0" @mousedown="leftUpStart()" @mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--上--> |
||||
|
<div class="direct-item" style="background-position:-30px 0" @mousedown="upStart()" @mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--右上--> |
||||
|
<div class="direct-item" style="background-position:-60px 0" @mousedown="rightUpStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--左--> |
||||
|
<div class="direct-item" style="background-position:0 -30px" @mousedown="leftStart()" @mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--自动--> |
||||
|
<div class="direct-item" style="background-position:-30px -30px" @click="autoStart()"> |
||||
|
</div> |
||||
|
<!--右--> |
||||
|
<div class="direct-item" style="background-position:-60px -30px" @mousedown="rightStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--左下--> |
||||
|
<div class="direct-item" style="background-position:0 -60px" @mousedown="leftDownStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--下--> |
||||
|
<div class="direct-item" style="background-position:-30px -60px" @mousedown="downStart()" |
||||
|
@mouseup="stopMove()"> |
||||
|
</div> |
||||
|
<!--右下--> |
||||
|
<div class="direct-item" style="background-position:-60px -60px" @mousedown="rightDownStart()" |
||||
|
@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> |
||||
|
<a-row> |
||||
|
<a-col span="1"></a-col> |
||||
|
<a-col span="19"> |
||||
|
<label class="demonstration">云台速度:{{ currentStep }}</label> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row type="flex"> |
||||
|
<a-col span="2"></a-col> |
||||
|
<a-col span="19"> |
||||
|
<input type="range" min="1" max="10" step="1" v-model="currentStep" /> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
</div> |
||||
|
<!-- 图片列表弹窗 --> |
||||
|
<!-- <img-list-dialog :visible.sync="screenSnapList.visible" |
||||
|
:camera-id="videoInfo.cameraId" |
||||
|
:title="screenSnapList.title" /> --> |
||||
|
</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 leftUpStart() { |
||||
|
let instruct = 'leftUp' |
||||
|
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 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 rightUpStart() { |
||||
|
let instruct = 'rightUp' |
||||
|
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 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 leftDownStart() { |
||||
|
let instruct = 'leftDown' |
||||
|
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 rightDownStart() { |
||||
|
let instruct = 'rightDown' |
||||
|
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 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 autoStart() { |
||||
|
if (autoFlag.value) { |
||||
|
stopMove() |
||||
|
autoFlag.value = false |
||||
|
} else { |
||||
|
leftStart() |
||||
|
autoFlag.value = true |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//变焦+ |
||||
|
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> |
||||
|
.camera-control { |
||||
|
color: #080000; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__bar { |
||||
|
background-color: #b00303; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__button { |
||||
|
border: 2px solid #848486; |
||||
|
} |
||||
|
|
||||
|
.camera-control .el-slider__runway { |
||||
|
width: 92%; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-operate { |
||||
|
display: -webkit-flex; |
||||
|
/* Safari */ |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-speed { |
||||
|
padding-top: 20px; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-speed input { |
||||
|
width: 40px; |
||||
|
color: black; |
||||
|
} |
||||
|
|
||||
|
.camera-control .camera-control-title { |
||||
|
padding-top: 7px; |
||||
|
text-align: center; |
||||
|
height: 35px; |
||||
|
line-height: 28px; |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.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); |
||||
|
} |
||||
|
</style> |
File diff suppressed because it is too large
Loading…
Reference in new issue