From aaff187cbf5bbdbf0a5e4e6a5b3ee44980889454 Mon Sep 17 00:00:00 2001
From: fajiao <1519100073@qq.com>
Date: Thu, 27 Oct 2022 10:02:43 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E8=B0=83=E7=94=A8?=
=?UTF-8?q?=E5=90=8E=E7=AB=AF=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=A0=87=E7=AD=BE?=
=?UTF-8?q?=E8=BF=BD=E8=B8=AA=E5=B1=95=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Frontend/package.json | 3 +
Frontend/src/api/cameraBase/cameraApi.ts | 7 +-
.../{cameraGroupApi.ts => markGroupApi.ts} | 7 +-
.../{cameraLabelApi.ts => markLabelApi.ts} | 22 +-
Frontend/src/api/cameraMark/markSearchApi.ts | 25 ++-
Frontend/src/api/index.ts | 1 +
Frontend/src/api/onvif/onvif.ts | 0
.../src/api/webrtcStreamer/webrtcStreamer.ts | 0
Frontend/src/utils/axios.ts | 4 +-
Frontend/src/views/page/cameraCenter.vue | 211 +++++++++++++++---
10 files changed, 223 insertions(+), 57 deletions(-)
rename Frontend/src/api/cameraMark/{cameraGroupApi.ts => markGroupApi.ts} (87%)
rename Frontend/src/api/cameraMark/{cameraLabelApi.ts => markLabelApi.ts} (55%)
create mode 100644 Frontend/src/api/onvif/onvif.ts
create mode 100644 Frontend/src/api/webrtcStreamer/webrtcStreamer.ts
diff --git a/Frontend/package.json b/Frontend/package.json
index 1aeb401..69b0110 100644
--- a/Frontend/package.json
+++ b/Frontend/package.json
@@ -9,9 +9,12 @@
"preview": "vite preview"
},
"dependencies": {
+ "@types/qs": "^6.9.7",
"ant-design-vue": "^3.2.13",
"axios": "^1.1.3",
+ "less": "^4.1.3",
"pinia": "^2.0.23",
+ "qs": "^6.11.0",
"vue": "^3.2.37",
"vue-router": "^4.1.5"
},
diff --git a/Frontend/src/api/cameraBase/cameraApi.ts b/Frontend/src/api/cameraBase/cameraApi.ts
index 4aebedd..069dc87 100644
--- a/Frontend/src/api/cameraBase/cameraApi.ts
+++ b/Frontend/src/api/cameraBase/cameraApi.ts
@@ -1,5 +1,6 @@
import {axios} from '@/utils/axios';
import {apiUrl} from "@/api";
+import qs from "qs";
enum Api {
Add = '/cbCamera/add',
@@ -12,11 +13,11 @@ enum Api {
const CisApiUrl = apiUrl.CisApiUrl;
-export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, params)
+export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, qs.stringify(params))
-export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, params)
+export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, qs.stringify(params))
-export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, params)
+export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, qs.stringify(params))
export const Get = (params?: any) => axios.get(CisApiUrl + Api.Get, {params: params})
diff --git a/Frontend/src/api/cameraMark/cameraGroupApi.ts b/Frontend/src/api/cameraMark/markGroupApi.ts
similarity index 87%
rename from Frontend/src/api/cameraMark/cameraGroupApi.ts
rename to Frontend/src/api/cameraMark/markGroupApi.ts
index 414e6f0..d83d409 100644
--- a/Frontend/src/api/cameraMark/cameraGroupApi.ts
+++ b/Frontend/src/api/cameraMark/markGroupApi.ts
@@ -1,5 +1,6 @@
import {axios} from '@/utils/axios';
import {apiUrl} from "@/api";
+import qs from "qs";
enum Api {
Add = '/cmMarkGroup/add',
@@ -12,11 +13,11 @@ enum Api {
const CisApiUrl = apiUrl.CisApiUrl;
-export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, params)
+export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, qs.stringify(params))
-export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, params)
+export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, qs.stringify(params))
-export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, params)
+export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, qs.stringify(params))
export const Get = (params?: any) => axios.get(CisApiUrl + Api.Get, {params: params})
diff --git a/Frontend/src/api/cameraMark/cameraLabelApi.ts b/Frontend/src/api/cameraMark/markLabelApi.ts
similarity index 55%
rename from Frontend/src/api/cameraMark/cameraLabelApi.ts
rename to Frontend/src/api/cameraMark/markLabelApi.ts
index 414e6f0..c9fd79d 100644
--- a/Frontend/src/api/cameraMark/cameraLabelApi.ts
+++ b/Frontend/src/api/cameraMark/markLabelApi.ts
@@ -1,22 +1,26 @@
import {axios} from '@/utils/axios';
import {apiUrl} from "@/api";
+import qs from 'qs';
enum Api {
- Add = '/cmMarkGroup/add',
- Update = '/cmMarkGroup/update',
- Delete = '/cmMarkGroup/delete',
- Get = '/cmMarkGroup/get',
- GetList = '/cmMarkGroup/getList',
- GetPageList = '/cmMarkGroup/getPageList',
+ Add = '/cmMarkLabel/add',
+ AddReturnId = '/cmMarkLabel/addReturnId',
+ Update = '/cmMarkLabel/update',
+ Delete = '/cmMarkLabel/delete',
+ Get = '/cmMarkLabel/get',
+ GetList = '/cmMarkLabel/getList',
+ GetPageList = '/cmMarkLabel/getPageList',
}
const CisApiUrl = apiUrl.CisApiUrl;
-export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, params)
+export const Add = (params?: any) => axios.post(CisApiUrl + Api.Add, qs.stringify(params))
-export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, params)
+export const AddReturnId = (params?: any) => axios.post(CisApiUrl + Api.AddReturnId, qs.stringify(params))
-export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, params)
+export const Update = (params?: any) => axios.post(CisApiUrl + Api.Update, qs.stringify(params))
+
+export const Delete = (params?: any) => axios.post(CisApiUrl + Api.Delete, qs.stringify(params))
export const Get = (params?: any) => axios.get(CisApiUrl + Api.Get, {params: params})
diff --git a/Frontend/src/api/cameraMark/markSearchApi.ts b/Frontend/src/api/cameraMark/markSearchApi.ts
index e2a5d0c..4c22de0 100644
--- a/Frontend/src/api/cameraMark/markSearchApi.ts
+++ b/Frontend/src/api/cameraMark/markSearchApi.ts
@@ -1,22 +1,29 @@
import {axios} from '@/utils/axios';
import {apiUrl} from "@/api";
+import qs from 'qs';
enum Api {
- ActiveCamera = '/markSearch/activeCamera',
- DeActiveCamera = '/markSearch/deActiveCamera',
- AddCameraMarkLabel = '/markSearch/addCameraMarkLabel',
- DeleteCameraMarkLabel = '/markSearch/deleteCameraMarkLabel',
- GetMarkLabelCalcResultList = '/markSearch/GetMarkLabelCalcResultList',
+ ActivateSearcher = '/markSearch/activateSearcher',
+ DeActiveSearcher = '/markSearch/deActiveSearcher',
+ IsExistSearcher = '/markSearch/isExistSearcher',
+ ActivateMarkLabel = '/markSearch/activateMarkLabel',
+ DeactivateMarkLabel = '/markSearch/deactivateMarkLabel',
+ IsExistMarkLabel = '/markSearch/isExistMarkLabel',
+ GetMarkLabelCalcResultList = '/markSearch/getMarkLabelCalcResultList',
}
const CisApiUrl = apiUrl.CisApiUrl;
-export const ActiveCamera = (params?: any) => axios.post(CisApiUrl + Api.ActiveCamera, params)
+export const ActiveSearcher = (params?: any) => axios.post(CisApiUrl + Api.ActivateSearcher, qs.stringify(params))
-export const DeActiveCamera = (params?: any) => axios.post(CisApiUrl + Api.DeActiveCamera, params)
+export const DeActiveSearcher = (params?: any) => axios.post(CisApiUrl + Api.DeActiveSearcher, qs.stringify(params))
-export const AddCameraMarkLabel = (params?: any) => axios.post(CisApiUrl + Api.AddCameraMarkLabel, params)
+export const IsExistSearcher = (params?: any) => axios.get(CisApiUrl + Api.IsExistSearcher, {params: params})
-export const DeleteCameraMarkLabel = (params?: any) => axios.post(CisApiUrl + Api.DeleteCameraMarkLabel, params)
+export const ActivateMarkLabel = (params?: any) => axios.post(CisApiUrl + Api.ActivateMarkLabel, qs.stringify(params))
+
+export const DeactivateMarkLabel = (params?: any) => axios.post(CisApiUrl + Api.DeactivateMarkLabel, qs.stringify(params))
+
+export const IsExistMarkLabel = (params?: any) => axios.get(CisApiUrl + Api.IsExistMarkLabel, {params: params})
export const GetMarkLabelCalcResultList = (params?: any) => axios.get(CisApiUrl + Api.GetMarkLabelCalcResultList, {params: params})
diff --git a/Frontend/src/api/index.ts b/Frontend/src/api/index.ts
index 216ba89..3b5f431 100644
--- a/Frontend/src/api/index.ts
+++ b/Frontend/src/api/index.ts
@@ -1,5 +1,6 @@
export const apiUrl = {
CisApiUrl: 'http://192.168.1.119:5000/api',
WebRtcUrl: 'http://192.168.1.119:8000',
+ OnvifApiUrl: ''
// CisApiUrl: 'https://192.168.1.119:5001/api'
}
diff --git a/Frontend/src/api/onvif/onvif.ts b/Frontend/src/api/onvif/onvif.ts
new file mode 100644
index 0000000..e69de29
diff --git a/Frontend/src/api/webrtcStreamer/webrtcStreamer.ts b/Frontend/src/api/webrtcStreamer/webrtcStreamer.ts
new file mode 100644
index 0000000..e69de29
diff --git a/Frontend/src/utils/axios.ts b/Frontend/src/utils/axios.ts
index 8a918b0..1dbc6b1 100644
--- a/Frontend/src/utils/axios.ts
+++ b/Frontend/src/utils/axios.ts
@@ -4,8 +4,8 @@ let apiBaseUrl = "/api";
const service = axios.create({
baseURL: apiBaseUrl, // api base_url
- timeout: 9000 // 请求超时时间
-})
+ timeout: 9000, // 请求超时时间
+});
export {
service as axios,
diff --git a/Frontend/src/views/page/cameraCenter.vue b/Frontend/src/views/page/cameraCenter.vue
index bbd439f..c700f39 100644
--- a/Frontend/src/views/page/cameraCenter.vue
+++ b/Frontend/src/views/page/cameraCenter.vue
@@ -4,26 +4,35 @@
-
+
@@ -35,36 +44,41 @@
import {defineComponent, ref} from 'vue';
import type {TreeProps} from 'ant-design-vue';
import * as cameraApi from '@/api/cameraBase/cameraApi';
+import * as markLabelApi from '@/api/cameraMark/markLabelApi';
+import * as markSearchApi from '@/api/cameraMark/markSearchApi';
import {apiUrl} from "@/api";
export default defineComponent({
data() {
return {
+ player: document.querySelector('#videoPlayer'),
+ canvas: document.querySelector('#videoCanvas'),
+ canvasWidth: 0,
+ canvasHeight: 0,
curSelectKey: '',
+ treeData: ref([]),
cameraMap: new Map(),
- webRtcServer: WebRtcStreamer
+ webRtcServer: WebRtcStreamer,
+ isActiveChoose: false,
}
},
- setup() {
- let treeData = ref([]);
- return {
- treeData,
- };
- },
created() {
this.$nextTick(() => {
+ this.player = document.querySelector('#videoPlayer');
+ this.canvas = document.querySelector('#videoCanvas');
+
this.loadTreeData();
this.loadVideoPlayer();
+ this.loadVideoCanvas();
});
},
methods: {
loadTreeData() {
- let that: any = this;
cameraApi.GetList().then((res) => {
- let list = res.data.data;
+ let list: Array = res.data.data;
for (let item of list) {
this.cameraMap.set(item.id, item);
- that.treeData.push({title: item.ip, key: item.id});
+ this.treeData!.push({title: item.ip, key: item.id});
}
});
},
@@ -73,43 +87,170 @@ export default defineComponent({
let key = selectedKeys[0];
if (this.curSelectKey !== key) {
this.curSelectKey = key;
- this.switchCamera(key);
+ // 模拟稳定选中相机功能,避免频繁切换
+ setTimeout(() => {
+ if (this.curSelectKey === key) {
+ this.switchCamera(key);
+ }
+ }, 1000);
}
},
loadVideoPlayer() {
let elmId = 'videoPlayer';
let url = apiUrl.WebRtcUrl;
this.webRtcServer = new WebRtcStreamer(elmId, url);
- document.querySelector('#videoPlayer').addEventListener('loadmetadata',function (){
- console.log("============================================================");
- console.log(this);
- console.log("============================================================");
+ },
+ loadVideoCanvas() {
+ window.addEventListener('resize', () => {
+ this.changeVideoCanvasSize();
});
},
+ changeVideoCanvasSize() {
+ this.canvasWidth = this.player.clientWidth;
+ this.canvasHeight = this.player.clientHeight;
+ },
+ mouseOverVideo() {
+ if (!this.isActiveChoose) return;
+ this.player.classList.add('activeChoose');
+ },
+ mouseOutVideo() {
+ if (!this.isActiveChoose) return;
+ this.player.classList.remove('activeChoose');
+ },
+ mouseDownVideo(e: MouseEvent) {
+ if (!this.isActiveChoose) return;
+ let cameraId = this.cameraMap.get(this.curSelectKey).id;
+ let name = 'markLabel-' + Date.now();
+ let videoWidth = this.player.videoWidth | 1920;
+ let videoHeight = this.player.videoHeight | 1080;
+ let canvasWidth = this.player.clientWidth;
+ let canvasHeight = this.player.clientHeight;
+ let canvasLeft = e.offsetX;
+ let canvasTop = e.offsetY;
+ let canvasLeftRatio = canvasLeft / canvasWidth;
+ let canvasTopRatio = canvasTop / canvasHeight;
+ let entity = {
+ CbCameraId: cameraId,
+ Name: name,
+ VideoWidth: videoWidth,
+ VideoHeight: videoHeight,
+ CanvasLeftRatio: canvasLeftRatio,
+ CanvasTopRatio: canvasTopRatio
+ }
+ console.log(entity);
+ markLabelApi.AddReturnId({
+ 'entity': entity
+ }).then((res) => {
+ let markLabelId: number = res.data.data;
+ if (markLabelId <= 0) return;
+ markSearchApi.ActivateMarkLabel({
+ 'cameraId': cameraId,
+ 'markLabelId': markLabelId
+ }).then((res) => {
+ let ret: boolean = res.data.data;
+ });
+ })
+ },
+ activateChoose() {
+ if (this.curSelectKey.length == 0) return;
+ this.isActiveChoose = true;
+ },
+ deactivateChoose() {
+ if (this.curSelectKey.length == 0) return;
+ this.isActiveChoose = false;
+ },
switchCamera(cameraId: string) {
console.log('camera switch.');
- let cameraObj = this.cameraMap.get(cameraId);
+
// step1, get camera obj.
- if (cameraObj == null) {
- console.log('camera not found.');
+ console.log('get camera obj.');
+ let cameraObj = this.cameraMap.get(cameraId);
+ if (!cameraObj) {
+ console.log('camera obj not found.');
return;
}
+ // object to proxy, ?
+ console.log(cameraObj,);
// step2, get camera rtsp url.
+ console.log('get camera rtsp url.');
let rtspUrl = this.getRtspUrl(cameraObj);
// step3, connect webrtc-steamer.
+ console.log('connect webrtc-steamer.');
this.webRtcServer.disconnect();
this.webRtcServer.connect(rtspUrl);
+ // step4, active camera searcher.
+ markSearchApi.IsExistSearcher({
+ 'cameraId': cameraObj.id
+ }).then((res) => {
+ let flag: boolean = res.data.data;
+ if (!flag) {
+ console.log('not exist searcher.');
+ markSearchApi.ActiveSearcher({
+ 'cameraId': cameraObj.id
+ }).then((res) => {
+ let flag: boolean = res.data.data;
+ console.log('activate searcher : ', flag);
+ if (flag) {
+ console.log('load camera labels');
+ this.loadMarkLabelsByLoop(cameraObj);
+ }
+ });
+ } else {
+ console.log('load camera labels');
+ this.loadMarkLabelsByLoop(cameraObj);
+ }
+ })
+
+ // step5, load camera labels.
},
getRtspUrl(cameraObj: any): string {
- return "rtsp://admin:hk123456@192.168.1.65:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1"
- }
+ // 模拟 onvif
+ return "rtsp://admin:hk123456@192.168.1.65:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1";
+ },
+ loadMarkLabelsByLoop(cameraObj: any, ms: number = 1000) {
+ if (this.curSelectKey !== cameraObj.id) {
+ console.log('load camera labels end.');
+ return;
+ }
+ this.loadMarkLabels(cameraObj);
+ setTimeout(() => {
+ this.loadMarkLabelsByLoop(cameraObj, ms);
+ }, ms);
+ },
+ loadMarkLabels(cameraObj: any) {
+ markSearchApi.GetMarkLabelCalcResultList({
+ 'cameraId': cameraObj.id
+ }).then((res) => {
+ let list: Array = res.data.data;
+ this.drawMarkLabels(list);
+ });
+ },
+ drawMarkLabels(markLabels: Array) {
+ let ctx = this.canvas.getContext('2d');
+ if (!ctx) return;
+ ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+ for (let markLabel of markLabels) {
+ if (!markLabel.inFlag) continue;
+ let x = Math.round(this.canvasWidth * markLabel.canvasLeftRatio);
+ let y = Math.round(this.canvasHeight * markLabel.canvasTopRatio);
+ x = this.canvasWidth * markLabel.canvasLeftRatio;
+ y = this.canvasHeight * markLabel.canvasTopRatio;
+ console.log(markLabel);
+ ctx.beginPath();
+ ctx.arc(x, y, 5, 0, 2 * Math.PI);
+ ctx.fillStyle = "red";
+ ctx.fill();
+ ctx.closePath();
+ }
+ },
},
- beforeDestroy() {
+ beforeUnmount() {
+ console.log('beforeUnmount.');
// 释放 webRtcServer
- if (this.webRtcServer === null) return;
+ if (!this.webRtcServer) return;
this.webRtcServer.disconnect();
this.webRtcServer = null;
}
@@ -117,5 +258,13 @@ export default defineComponent({
\ No newline at end of file