| | |
| | | </div> |
| | | </template> |
| | | <script> |
| | | import Wfs from "./wfs"; |
| | | import VideoRuleData from "@/Pool/VideoRuleData"; |
| | | import TreeDataPool from "@/Pool/TreeData"; |
| | | import { getAllPolygon } from "@/api/polygon"; |
| | | import polygonCanvas from "@/components/canvas"; |
| | | import Wfs from "./wfs" |
| | | import VideoRuleData from "@/Pool/VideoRuleData" |
| | | import TreeDataPool from "@/Pool/TreeData" |
| | | import { getAllPolygon } from "@/api/polygon" |
| | | import polygonCanvas from "@/components/canvas" |
| | | export default { |
| | | name: "CameraPlayer", |
| | | props: { |
| | |
| | | default: false |
| | | } |
| | | }, |
| | | |
| | | computed: { |
| | | |
| | | computed: { |
| | | poster() { |
| | | return "/images/player/player_poster.gif?t=" + Math.random() |
| | | } |
| | |
| | | ctx: null, |
| | | canvasWidth: 0, |
| | | canvasHeight: 0, |
| | | }; |
| | | algoDataSocket: null |
| | | } |
| | | }, |
| | | watch: { |
| | | // "TreeDataPool.selectedNode": async function(node){ |
| | | // if(node){ |
| | | // console.log('TreeDataPool.selectedNode') |
| | | // console.log(node) |
| | | // //this.Camera.cameraId = node.id; |
| | | // const res = await getAllPolygon({cameraId: node.id}); |
| | | |
| | | // this.canvasData.line = res.data.line; |
| | | // this.canvasData.rect = res.data.rect; |
| | | // this.canvasData.arrow = res.data.arrow; |
| | | // this.canvasData.polygon = res.data.polygon; |
| | | // console.log(this.canvasData) |
| | | // this.clickSelect(this.canvasData); |
| | | // } |
| | | // }, |
| | | |
| | | rtspUrl: function (newVal, oldVal) { |
| | | rtspUrl: function(newVal, oldVal) { |
| | | if (newVal !== oldVal) { |
| | | if (this.wfs.config) { |
| | | this.wfs.destroy(); |
| | | this.wfs.destroy() |
| | | !!this.algoDataSocket && this.algoDataSocket.close() |
| | | } |
| | | this.$nextTick(() => { |
| | | this.clickStart(); |
| | | }); |
| | | this.clickStart() |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.clickStart() |
| | | this.$nextTick(() => { |
| | | this.canvas = this.$refs.areaCanvas |
| | | this.ctx = this.canvas.getContext("2d") |
| | | this.ctx.lineWidth = 1 |
| | | this.initArea() |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | !!this.wfs && this.wfs.destroy() |
| | | this.wfsId = "" |
| | | !!this.algoDataSocket && this.algoDataSocket.close() |
| | | }, |
| | | methods: { |
| | | checkConnect(id) { |
| | |
| | | |
| | | if (this.wfs.websocketLoader && this.wfs.websocketLoader.client) { |
| | | if (this.wfs.websocketLoader.client.disconnected) { |
| | | this.clickStart(); |
| | | this.clickStart() |
| | | console.log("实时视频已断开,正在重连") |
| | | return |
| | | } |
| | | } |
| | | |
| | | let _this = this; |
| | | let _this = this |
| | | setTimeout(() => { |
| | | _this.checkConnect(id) |
| | | }, 10000) |
| | | }, |
| | | clickStart() { |
| | | if (this.rtspUrl == "") { |
| | | return; |
| | | return |
| | | } |
| | | |
| | | let cameraId = this.cameraID; |
| | | let cameraId = this.cameraID |
| | | if (cameraId == "") { |
| | | cameraId = this.getUuid(); |
| | | cameraId = this.getUuid() |
| | | } |
| | | |
| | | if (Wfs.isSupported()) { |
| | | let wsAddr = this.wsAddr; |
| | | let wsAddr = this.wsAddr |
| | | let cameraInfo = { |
| | | cameraID: cameraId, |
| | | rtspUrl: this.rtspUrl, |
| | | isRunning: this.isRunning, |
| | | isGb28181: this.isGb |
| | | }; |
| | | } |
| | | |
| | | // let camera = document.getElementById(this.cameraID); |
| | | let camera = this.$refs.videoPlayer; |
| | | this.wfs = new Wfs(); |
| | | let randomId = this.getUuid(); |
| | | this.wfsId = randomId; |
| | | this.wfs.attachMedia(camera, "chX", "H264Raw", wsAddr, cameraInfo); |
| | | let camera = this.$refs.videoPlayer |
| | | this.wfs = new Wfs() |
| | | let randomId = this.getUuid() |
| | | this.wfsId = randomId |
| | | this.wfs.attachMedia(camera, "chX", "H264Raw", wsAddr, cameraInfo) |
| | | |
| | | this.checkConnect(randomId) |
| | | } |
| | | }, |
| | | getUuid() { |
| | | var s = []; |
| | | var hexDigits = "0123456789abcdefghijkopqrst"; |
| | | var s = [] |
| | | var hexDigits = "0123456789abcdefghijkopqrst" |
| | | for (var i = 0; i < 36; i++) { |
| | | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); |
| | | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1) |
| | | } |
| | | s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 |
| | | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 |
| | | s[8] = s[13] = s[18] = s[23] = "-"; |
| | | var uuid = s.join(""); |
| | | return uuid; |
| | | s[14] = "4" // bits 12-15 of the time_hi_and_version field to 0010 |
| | | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01 |
| | | s[8] = s[13] = s[18] = s[23] = "-" |
| | | var uuid = s.join("") |
| | | return uuid |
| | | }, |
| | | fullScreen() { |
| | | this.$refs.videoPlayer.webkitRequestFullScreen(); |
| | | this.$refs.videoPlayer.webkitRequestFullScreen() |
| | | }, |
| | | // 回显cavas数据 |
| | | // 点击选中变色 将当前页面所有路径重绘判断当前鼠标的坐标在哪个图形内 如果不传坐标参数就是回显的方法 |
| | | clickSelect(e) { |
| | | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); |
| | | let _this = this; // 集合中遍历需要将this转存一下使用 |
| | | _this.canvasData.line.forEach(function (v, i) { |
| | | _this.ctx.strokeStyle = "yellow"; |
| | | _this.ctx.beginPath(); |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion); |
| | | _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion); |
| | | _this.ctx.stroke(); |
| | | // _this.showRemarks( |
| | | // v.location[0].x / _this.showProportion, |
| | | // v.location[0].y / _this.showProportion, |
| | | // v.name |
| | | // ); |
| | | _this.canvas.style.cursor = "default"; |
| | | }); |
| | | _this.canvasData.rect.forEach(function (v, i) { |
| | | _this.ctx.strokeStyle = "yellow"; |
| | | _this.ctx.beginPath(); |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion); |
| | | _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion); |
| | | _this.ctx.lineTo(v.location[2].x / _this.showProportion, v.location[2].y / _this.showProportion); |
| | | _this.ctx.lineTo(v.location[3].x / _this.showProportion, v.location[3].y / _this.showProportion); |
| | | _this.ctx.lineTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion); |
| | | _this.ctx.stroke(); |
| | | // _this.showRemarks( |
| | | // v.location[0].x / _this.showProportion, |
| | | // v.location[0].y / _this.showProportion, |
| | | // v.name |
| | | // ); |
| | | _this.canvas.style.cursor = "default"; |
| | | |
| | | }); |
| | | _this.canvasData.arrow.forEach(function (v, i) { |
| | | _this.ctx.strokeStyle = "yellow"; |
| | | this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) |
| | | let _this = this // 集合中遍历需要将this转存一下使用 |
| | | _this.canvasData.line.forEach(function(v, i) { |
| | | _this.ctx.strokeStyle = "yellow" |
| | | _this.ctx.beginPath() |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion) |
| | | _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion) |
| | | _this.ctx.stroke() |
| | | _this.canvas.style.cursor = "default" |
| | | }) |
| | | _this.canvasData.rect.forEach(function(v, i) { |
| | | _this.ctx.strokeStyle = "yellow" |
| | | _this.ctx.beginPath() |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion) |
| | | _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion) |
| | | _this.ctx.lineTo(v.location[2].x / _this.showProportion, v.location[2].y / _this.showProportion) |
| | | _this.ctx.lineTo(v.location[3].x / _this.showProportion, v.location[3].y / _this.showProportion) |
| | | _this.ctx.lineTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion) |
| | | _this.ctx.stroke() |
| | | _this.canvas.style.cursor = "default" |
| | | }) |
| | | _this.canvasData.arrow.forEach(function(v, i) { |
| | | _this.ctx.strokeStyle = "yellow" |
| | | _this.drawArrow( |
| | | _this.ctx, |
| | | v.location[0].x / _this.showProportion, |
| | |
| | | 20, |
| | | 30, |
| | | "yellow" |
| | | ); |
| | | // 绘制方法 |
| | | // _this.showRemarks( |
| | | // v.location[0].x / _this.showProportion, |
| | | // v.location[0].y / _this.showProportion, |
| | | // v.name |
| | | // ); |
| | | _this.canvas.style.cursor = "default"; |
| | | |
| | | }); |
| | | _this.canvasData.polygon.forEach(function (v, i) { |
| | | ) |
| | | _this.canvas.style.cursor = "default" |
| | | }) |
| | | _this.canvasData.polygon.forEach(function(v, i) { |
| | | if (v.location.length === 0) { |
| | | return; |
| | | return |
| | | } |
| | | _this.ctx.strokeStyle = "yellow"; |
| | | _this.ctx.beginPath(); |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportionY); |
| | | _this.ctx.strokeStyle = "yellow" |
| | | _this.ctx.beginPath() |
| | | _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportionY) |
| | | for (let i = 1; i < v.location.length; i++) { |
| | | _this.ctx.lineTo(v.location[i].x / _this.showProportion, v.location[i].y / _this.showProportionY); |
| | | _this.ctx.lineTo(v.location[i].x / _this.showProportion, v.location[i].y / _this.showProportionY) |
| | | } |
| | | _this.ctx.closePath(); |
| | | _this.ctx.stroke(); |
| | | // _this.showRemarks( |
| | | // v.location[v.location.length - 1].x / _this.showProportion, |
| | | // v.location[v.location.length - 1].y / _this.showProportionY, |
| | | // v.name |
| | | // ); |
| | | _this.canvas.style.cursor = "default"; |
| | | |
| | | }); |
| | | _this.ctx.closePath() |
| | | _this.ctx.stroke() |
| | | _this.canvas.style.cursor = "default" |
| | | }) |
| | | }, |
| | | |
| | | |
| | | // 箭头绘制函数 |
| | | drawArrow(ctx, fromX, fromY, toX, toY, theta=30, headlen=10, width=1, color="yellow") { |
| | | drawArrow(ctx, fromX, fromY, toX, toY, theta = 30, headlen = 10, width = 1, color = "yellow") { |
| | | // ctx:Canvas绘图环境 |
| | | // fromX, fromY:起点坐标(也可以换成p1,只不过它是一个数组) |
| | | // toX, toY:终点坐标 (也可以换成p2,只不过它是一个数组) |
| | |
| | | // width = typeof width !== "undefined" ? width : 1; |
| | | // color = typeof color !== "undefined" ? color : "yellow"; |
| | | // 计算各角度和对应的P2,P3坐标 |
| | | let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI; |
| | | let angle1 = ((angle + theta) * Math.PI) / 180; |
| | | let angle2 = ((angle - theta) * Math.PI) / 180; |
| | | let topX = headlen * Math.cos(angle1); |
| | | let topY = headlen * Math.sin(angle1); |
| | | let botX = headlen * Math.cos(angle2); |
| | | let botY = headlen * Math.sin(angle2); |
| | | let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI |
| | | let angle1 = ((angle + theta) * Math.PI) / 180 |
| | | let angle2 = ((angle - theta) * Math.PI) / 180 |
| | | let topX = headlen * Math.cos(angle1) |
| | | let topY = headlen * Math.sin(angle1) |
| | | let botX = headlen * Math.cos(angle2) |
| | | let botY = headlen * Math.sin(angle2) |
| | | |
| | | ctx.save(); |
| | | ctx.beginPath(); |
| | | let arrowX = fromX - topX; |
| | | let arrowY = fromY - topY; |
| | | ctx.moveTo(arrowX, arrowY); |
| | | ctx.moveTo(fromX, fromY); |
| | | ctx.lineTo(toX, toY); |
| | | arrowX = toX + topX; |
| | | arrowY = toY + topY; |
| | | ctx.moveTo(arrowX, arrowY); |
| | | ctx.lineTo(toX, toY); |
| | | arrowX = toX + botX; |
| | | arrowY = toY + botY; |
| | | ctx.lineTo(arrowX, arrowY); |
| | | ctx.strokeStyle = color; |
| | | ctx.lineWidth = width; |
| | | ctx.stroke(); |
| | | ctx.restore(); |
| | | ctx.save() |
| | | ctx.beginPath() |
| | | let arrowX = fromX - topX |
| | | let arrowY = fromY - topY |
| | | ctx.moveTo(arrowX, arrowY) |
| | | ctx.moveTo(fromX, fromY) |
| | | ctx.lineTo(toX, toY) |
| | | arrowX = toX + topX |
| | | arrowY = toY + topY |
| | | ctx.moveTo(arrowX, arrowY) |
| | | ctx.lineTo(toX, toY) |
| | | arrowX = toX + botX |
| | | arrowY = toY + botY |
| | | ctx.lineTo(arrowX, arrowY) |
| | | ctx.strokeStyle = color |
| | | ctx.lineWidth = width |
| | | ctx.stroke() |
| | | ctx.restore() |
| | | }, |
| | | |
| | | |
| | | // 回显图形备注 |
| | | showRemarks(x, y, remarks) { |
| | | this.ctx.moveTo(x, y - 10); // 因为放大之后是y-20,所以缩小版的为y-10 |
| | | this.ctx.fillStyle = "green"; // 设置填充颜色为绿色 |
| | | this.ctx.font = '10px "微软雅黑"'; // 设置字体 |
| | | this.ctx.textBaseline = "bottom"; // 设置字体底线对齐绘制基线 |
| | | this.ctx.textAlign = "left"; // 设置字体对齐的方式 |
| | | this.ctx.fillText(remarks, x, y - 10); // 填充文字 |
| | | this.ctx.moveTo(x, y - 10) // 因为放大之后是y-20,所以缩小版的为y-10 |
| | | this.ctx.fillStyle = "green" // 设置填充颜色为绿色 |
| | | this.ctx.font = '10px "微软雅黑"' // 设置字体 |
| | | this.ctx.textBaseline = "bottom" // 设置字体底线对齐绘制基线 |
| | | this.ctx.textAlign = "left" // 设置字体对齐的方式 |
| | | this.ctx.fillText(remarks, x, y - 10) // 填充文字 |
| | | }, |
| | | getCanvasData(data) { |
| | | let polyon = { ...data }; |
| | | polyon.camera_id = this.Camera.cameraId; |
| | | savePolygon(polyon).then(rsp => { |
| | | this.Camera.getPolygon(); |
| | | this.Camera.getCameraTask(); |
| | | }); |
| | | let polyon = { ...data } |
| | | polyon.camera_id = this.Camera.cameraId |
| | | savePolygon(polyon).then((rsp) => { |
| | | this.Camera.getPolygon() |
| | | this.Camera.getCameraTask() |
| | | }) |
| | | }, |
| | | setWidthHeight(){ |
| | | this.canvasWidth = this.$refs.videoPlayer.offsetWidth; |
| | | this.canvasHeight = this.$refs.videoPlayer.offsetHeight; |
| | | console.log(this.canvasWidth,this.canvasHeight) |
| | | setWidthHeight() { |
| | | this.canvasWidth = this.$refs.videoPlayer.offsetWidth |
| | | this.canvasHeight = this.$refs.videoPlayer.offsetHeight |
| | | console.log(this.canvasWidth, this.canvasHeight) |
| | | }, |
| | | async initArea(){ |
| | | console.log('init') |
| | | const res = await getAllPolygon({cameraId: this.TreeDataPool.selectedNode.id}); |
| | | this.canvasData.line = res.data.line; |
| | | this.canvasData.rect = res.data.rect; |
| | | this.canvasData.arrow = res.data.arrow; |
| | | this.canvasData.polygon = res.data.polygon; |
| | | async initArea() { |
| | | console.log("init") |
| | | const res = await getAllPolygon({ cameraId: this.TreeDataPool.selectedNode.id }) |
| | | this.canvasData.line = res.data.line |
| | | this.canvasData.rect = res.data.rect |
| | | this.canvasData.arrow = res.data.arrow |
| | | this.canvasData.polygon = res.data.polygon |
| | | console.log(this.canvasData) |
| | | // this.canvasData = { |
| | | // line: [], |
| | | // arrow: [], |
| | | // polygon: [{id:'uuid', name: '多边形1', location: [{ x: 735, y: 155 }, { x: 830, y: 156 }, { x: 809, y: 351 }, { x: 809, y: 364 }, { x: 753, y: 396 }, { x: 755, y: 520 },{ x: 706, y: 524 },{ x: 722, y: 392 },{x:758,y:280},{ x: 735, y: 155 }] }], |
| | | // //rect: rsp.data.rect |
| | | // rect: [] |
| | | // }; |
| | | this.clickSelect(this.canvasData); |
| | | this.clickSelect(this.canvasData) |
| | | }, |
| | | initAlgoDataWebScoket() { |
| | | if (typeof WebSocket === "undefined") { |
| | | console.log("error,您的浏览器不支持socket") |
| | | } else { |
| | | this.algoDataSocket = new WebSocket() |
| | | this.algoDataSocket.onopen = () => { |
| | | console.log("socket连接成功") |
| | | } |
| | | this.algoDataSocket.onerror = () => { |
| | | console.log("连接错误") |
| | | } |
| | | this.algoDataSocket.onmessage = (msg) => { |
| | | console.log(msg) |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | //获取video宽高并给区域canvas赋值 |
| | | //this.setWidthHeight(); |
| | | this.clickStart(); |
| | | |
| | | window.addEventListener('resize',()=>{ |
| | | //this.setWidthHeight(); |
| | | //this.initArea(); |
| | | }); |
| | | this.$nextTick(()=>{ |
| | | this.canvas = this.$refs.areaCanvas; |
| | | this.ctx = this.canvas.getContext("2d"); |
| | | this.ctx.lineWidth = 1; |
| | | |
| | | this.initArea(); |
| | | |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | this.wfs.destroy(); |
| | | this.wfsId = ""; |
| | | } |
| | | }; |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | #area-canvas{ |
| | | #area-canvas { |
| | | background: transparent; |
| | | position: absolute; |
| | | top: 0; |