Browse Source

feat: 完善调用后端,实现标签追踪展示

master
fajiao 2 years ago
parent
commit
aaff187cbf
  1. 3
      Frontend/package.json
  2. 7
      Frontend/src/api/cameraBase/cameraApi.ts
  3. 7
      Frontend/src/api/cameraMark/markGroupApi.ts
  4. 22
      Frontend/src/api/cameraMark/markLabelApi.ts
  5. 25
      Frontend/src/api/cameraMark/markSearchApi.ts
  6. 1
      Frontend/src/api/index.ts
  7. 0
      Frontend/src/api/onvif/onvif.ts
  8. 0
      Frontend/src/api/webrtcStreamer/webrtcStreamer.ts
  9. 4
      Frontend/src/utils/axios.ts
  10. 211
      Frontend/src/views/page/cameraCenter.vue

3
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"
},

7
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})

7
Frontend/src/api/cameraMark/cameraGroupApi.ts → 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})

22
Frontend/src/api/cameraMark/cameraLabelApi.ts → 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})

25
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})

1
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'
}

0
Frontend/src/api/onvif/onvif.ts

0
Frontend/src/api/webrtcStreamer/webrtcStreamer.ts

4
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,

211
Frontend/src/views/page/cameraCenter.vue

@ -4,26 +4,35 @@
<a-layout-sider width="200" style="background: #fff">
<div style="background: aqua; height: 50%">
<a-tree
:tree-data="treeData"
@select="selectTreeNode"
<a-tree style="background: aqua;"
:tree-data="treeData"
@select="selectTreeNode"
/>
</div>
<div style="background: bisque; height: 50%">
<a-button @click="activateChoose">添加标签</a-button>
<a-button @click="deactivateChoose">取消添加标签</a-button>
</div>
</a-layout-sider>
<a-layout style="padding: 0 16px 16px;">
<a-layout style="padding: 4px;">
<div id="videoWrapper">
<div id="videoCanvas">
<video id="videoPlayer" autoplay muted>
<canvas ref="videoCanvas" id="videoCanvas"
:width="canvasWidth" :height="canvasHeight"
:style="{width:canvasWidth+'px',height:canvasHeight+'px'}"
</video>
</div>
>
</canvas>
<video ref="videoPlayer" id="videoPlayer" style="height: 100%;width: 100%" autoplay muted
@loadedmetadata="changeVideoCanvasSize"
@mouseover="mouseOverVideo"
@mouseout="mouseOutVideo"
@mousedown="mouseDownVideo"
>
</video>
</div>
</a-layout>
@ -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: <HTMLVideoElement>document.querySelector('#videoPlayer'),
canvas: <HTMLCanvasElement>document.querySelector('#videoCanvas'),
canvasWidth: 0,
canvasHeight: 0,
curSelectKey: '',
treeData: ref<TreeProps['treeData']>([]),
cameraMap: new Map<string, any>(),
webRtcServer: WebRtcStreamer
webRtcServer: WebRtcStreamer,
isActiveChoose: false,
}
},
setup() {
let treeData = ref<TreeProps['treeData']>([]);
return {
treeData,
};
},
created() {
this.$nextTick(() => {
this.player = <HTMLVideoElement>document.querySelector('#videoPlayer');
this.canvas = <HTMLCanvasElement>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<any> = 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<any> = res.data.data;
this.drawMarkLabels(list);
});
},
drawMarkLabels(markLabels: Array<any>) {
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({
</script>
<style>
.activeChoose {
cursor: pointer;
}
#videoCanvas {
position: absolute;
width: 100%;
height: 100%;
}
</style>
Loading…
Cancel
Save