Migrated camera.cv/camera.ffmpeg/camera.gstreamer UI panels
This commit is contained in:
parent
748609c6f4
commit
41acb02eb0
21 changed files with 470 additions and 7 deletions
2
platypush/backend/http/dist/index.html
vendored
2
platypush/backend/http/dist/index.html
vendored
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-134ec1dc.849ccfd5.css" rel="prefetch"><link href="/static/css/chunk-13b07ca5.029dd736.css" rel="prefetch"><link href="/static/css/chunk-1653b664.5b949e24.css" rel="prefetch"><link href="/static/css/chunk-23726328.7e460329.css" rel="prefetch"><link href="/static/css/chunk-2ca39dde.efa1eae8.css" rel="prefetch"><link href="/static/css/chunk-2f304dee.a8a2d99a.css" rel="prefetch"><link href="/static/css/chunk-487896e7.b7730bd4.css" rel="prefetch"><link href="/static/css/chunk-49211740.43a25f0f.css" rel="prefetch"><link href="/static/css/chunk-4dae396b.92b3713e.css" rel="prefetch"><link href="/static/css/chunk-5145872a.197de139.css" rel="prefetch"><link href="/static/css/chunk-595ffc05.678c9c97.css" rel="prefetch"><link href="/static/css/chunk-64076603.e451beea.css" rel="prefetch"><link href="/static/css/chunk-675c7703.75b51be7.css" rel="prefetch"><link href="/static/css/chunk-792fd41e.4d467174.css" rel="prefetch"><link href="/static/css/chunk-7fae0422.c233115f.css" rel="prefetch"><link href="/static/css/chunk-d22da0c0.7c71cffb.css" rel="prefetch"><link href="/static/css/chunk-d28a86c4.cdd32c08.css" rel="prefetch"><link href="/static/css/chunk-da9476ec.f1965e2d.css" rel="prefetch"><link href="/static/css/chunk-ee62c128.44bbe779.css" rel="prefetch"><link href="/static/js/chunk-134ec1dc.87638287.js" rel="prefetch"><link href="/static/js/chunk-13b07ca5.11833bcd.js" rel="prefetch"><link href="/static/js/chunk-1653b664.4bba37ff.js" rel="prefetch"><link href="/static/js/chunk-23726328.7a638dfb.js" rel="prefetch"><link href="/static/js/chunk-2ca39dde.bfb67629.js" rel="prefetch"><link href="/static/js/chunk-2d0b270c.82d7f897.js" rel="prefetch"><link href="/static/js/chunk-2d0c1eb0.2fc91e77.js" rel="prefetch"><link href="/static/js/chunk-2d0cc2be.71e3fcd8.js" rel="prefetch"><link href="/static/js/chunk-2d2091df.90a98553.js" rel="prefetch"><link href="/static/js/chunk-2d21b0dc.465e6abf.js" rel="prefetch"><link href="/static/js/chunk-2d21da1a.707bd994.js" rel="prefetch"><link href="/static/js/chunk-2d231217.5ff519da.js" rel="prefetch"><link href="/static/js/chunk-2d237d41.b4b87abb.js" rel="prefetch"><link href="/static/js/chunk-2f304dee.649e4dc7.js" rel="prefetch"><link href="/static/js/chunk-487896e7.69cdcafb.js" rel="prefetch"><link href="/static/js/chunk-49211740.e4dea096.js" rel="prefetch"><link href="/static/js/chunk-4dae396b.0ee6bb40.js" rel="prefetch"><link href="/static/js/chunk-5145872a.f0bd0577.js" rel="prefetch"><link href="/static/js/chunk-595ffc05.8affd7fe.js" rel="prefetch"><link href="/static/js/chunk-64076603.2c344ed9.js" rel="prefetch"><link href="/static/js/chunk-675c7703.7c7378cd.js" rel="prefetch"><link href="/static/js/chunk-792fd41e.aca41198.js" rel="prefetch"><link href="/static/js/chunk-7fae0422.0d9be069.js" rel="prefetch"><link href="/static/js/chunk-d22da0c0.da01e99e.js" rel="prefetch"><link href="/static/js/chunk-d28a86c4.d0c1f74e.js" rel="prefetch"><link href="/static/js/chunk-da9476ec.f8c15985.js" rel="prefetch"><link href="/static/js/chunk-ee62c128.c11fb53e.js" rel="prefetch"><link href="/static/css/app.a835db3a.css" rel="preload" as="style"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="preload" as="style"><link href="/static/js/app.2721d165.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.948dc2e5.js" rel="preload" as="script"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="stylesheet"><link href="/static/css/app.a835db3a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.948dc2e5.js"></script><script src="/static/js/app.2721d165.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>platypush</title><link href="/static/css/chunk-0a9aba75.8a0131ad.css" rel="prefetch"><link href="/static/css/chunk-134ec1dc.849ccfd5.css" rel="prefetch"><link href="/static/css/chunk-13b07ca5.029dd736.css" rel="prefetch"><link href="/static/css/chunk-1653b664.5b949e24.css" rel="prefetch"><link href="/static/css/chunk-23726328.7e460329.css" rel="prefetch"><link href="/static/css/chunk-2ca39dde.efa1eae8.css" rel="prefetch"><link href="/static/css/chunk-2f304dee.a8a2d99a.css" rel="prefetch"><link href="/static/css/chunk-487896e7.b7730bd4.css" rel="prefetch"><link href="/static/css/chunk-49211740.43a25f0f.css" rel="prefetch"><link href="/static/css/chunk-4dae396b.92b3713e.css" rel="prefetch"><link href="/static/css/chunk-5145872a.197de139.css" rel="prefetch"><link href="/static/css/chunk-595ffc05.678c9c97.css" rel="prefetch"><link href="/static/css/chunk-64076603.e451beea.css" rel="prefetch"><link href="/static/css/chunk-675c7703.75b51be7.css" rel="prefetch"><link href="/static/css/chunk-792fd41e.4d467174.css" rel="prefetch"><link href="/static/css/chunk-7fae0422.c233115f.css" rel="prefetch"><link href="/static/css/chunk-d22da0c0.7c71cffb.css" rel="prefetch"><link href="/static/css/chunk-d28a86c4.cdd32c08.css" rel="prefetch"><link href="/static/css/chunk-da9476ec.f1965e2d.css" rel="prefetch"><link href="/static/css/chunk-ee62c128.44bbe779.css" rel="prefetch"><link href="/static/js/chunk-0a9aba75.bc40521f.js" rel="prefetch"><link href="/static/js/chunk-134ec1dc.87638287.js" rel="prefetch"><link href="/static/js/chunk-13b07ca5.11833bcd.js" rel="prefetch"><link href="/static/js/chunk-1653b664.4bba37ff.js" rel="prefetch"><link href="/static/js/chunk-23726328.7a638dfb.js" rel="prefetch"><link href="/static/js/chunk-2ca39dde.bfb67629.js" rel="prefetch"><link href="/static/js/chunk-2d0b270c.82d7f897.js" rel="prefetch"><link href="/static/js/chunk-2d0c1eb0.2fc91e77.js" rel="prefetch"><link href="/static/js/chunk-2d0c229a.c6f13c92.js" rel="prefetch"><link href="/static/js/chunk-2d0cc2be.71e3fcd8.js" rel="prefetch"><link href="/static/js/chunk-2d0da3df.99de332b.js" rel="prefetch"><link href="/static/js/chunk-2d208116.4f67ac14.js" rel="prefetch"><link href="/static/js/chunk-2d2091df.90a98553.js" rel="prefetch"><link href="/static/js/chunk-2d21b0dc.465e6abf.js" rel="prefetch"><link href="/static/js/chunk-2d21da1a.707bd994.js" rel="prefetch"><link href="/static/js/chunk-2d231217.5ff519da.js" rel="prefetch"><link href="/static/js/chunk-2d237d41.b4b87abb.js" rel="prefetch"><link href="/static/js/chunk-2f304dee.649e4dc7.js" rel="prefetch"><link href="/static/js/chunk-487896e7.69cdcafb.js" rel="prefetch"><link href="/static/js/chunk-49211740.e4dea096.js" rel="prefetch"><link href="/static/js/chunk-4dae396b.0ee6bb40.js" rel="prefetch"><link href="/static/js/chunk-5145872a.f0bd0577.js" rel="prefetch"><link href="/static/js/chunk-595ffc05.8affd7fe.js" rel="prefetch"><link href="/static/js/chunk-64076603.2c344ed9.js" rel="prefetch"><link href="/static/js/chunk-675c7703.7c7378cd.js" rel="prefetch"><link href="/static/js/chunk-792fd41e.aca41198.js" rel="prefetch"><link href="/static/js/chunk-7fae0422.0d9be069.js" rel="prefetch"><link href="/static/js/chunk-d22da0c0.da01e99e.js" rel="prefetch"><link href="/static/js/chunk-d28a86c4.d0c1f74e.js" rel="prefetch"><link href="/static/js/chunk-da9476ec.f8c15985.js" rel="prefetch"><link href="/static/js/chunk-ee62c128.c11fb53e.js" rel="prefetch"><link href="/static/css/app.a835db3a.css" rel="preload" as="style"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="preload" as="style"><link href="/static/js/app.20af947b.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.948dc2e5.js" rel="preload" as="script"><link href="/static/css/chunk-vendors.5dad8b00.css" rel="stylesheet"><link href="/static/css/app.a835db3a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but platypush doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.948dc2e5.js"></script><script src="/static/js/app.20af947b.js"></script></body></html>
|
1
platypush/backend/http/dist/static/css/chunk-0a9aba75.8a0131ad.css
vendored
Normal file
1
platypush/backend/http/dist/static/css/chunk-0a9aba75.8a0131ad.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/app.20af947b.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/app.20af947b.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/app.20af947b.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/app.20af947b.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/chunk-0a9aba75.bc40521f.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-0a9aba75.bc40521f.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
platypush/backend/http/dist/static/js/chunk-0a9aba75.bc40521f.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-0a9aba75.bc40521f.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
platypush/backend/http/dist/static/js/chunk-2d0c229a.c6f13c92.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-2d0c229a.c6f13c92.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0c229a"],{"48aa":function(e,a,r){"use strict";r.r(a);var n=r("7a23");function t(e,a,r,t,c,u){var m=Object(n["z"])("Camera");return Object(n["r"])(),Object(n["e"])(m,{"camera-plugin":"gstreamer"})}var c=r("1ed9"),u={name:"CameraGstreamer",components:{Camera:c["default"]}};u.render=t;a["default"]=u}}]);
|
||||
//# sourceMappingURL=chunk-2d0c229a.c6f13c92.js.map
|
1
platypush/backend/http/dist/static/js/chunk-2d0c229a.c6f13c92.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-2d0c229a.c6f13c92.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///./src/components/panels/CameraGstreamer/Index.vue","webpack:///./src/components/panels/CameraGstreamer/Index.vue?f193"],"names":["camera-plugin","name","components","Camera","render"],"mappings":"wNACE,eAAoC,GAA5BA,gBAAc,c,gBAMT,GACbC,KAAM,kBACNC,WAAY,CAACC,OAAA,eCNf,EAAOC,OAASA,EAED","file":"static/js/chunk-2d0c229a.c6f13c92.js","sourcesContent":["<template>\n <Camera camera-plugin=\"gstreamer\" />\n</template>\n\n<script>\nimport Camera from \"@/components/panels/Camera/Index\";\n\nexport default {\n name: \"CameraGstreamer\",\n components: {Camera},\n}\n</script>\n","import { render } from \"./Index.vue?vue&type=template&id=6c669f2b\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script"],"sourceRoot":""}
|
2
platypush/backend/http/dist/static/js/chunk-2d0da3df.99de332b.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-2d0da3df.99de332b.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0da3df"],{"6b85":function(e,a,n){"use strict";n.r(a);var r=n("7a23");function c(e,a,n,c,t,d){var u=Object(r["z"])("Camera");return Object(r["r"])(),Object(r["e"])(u,{"camera-plugin":"cv"})}var t=n("1ed9"),d={name:"CameraCv",components:{Camera:t["default"]}};d.render=c;a["default"]=d}}]);
|
||||
//# sourceMappingURL=chunk-2d0da3df.99de332b.js.map
|
1
platypush/backend/http/dist/static/js/chunk-2d0da3df.99de332b.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-2d0da3df.99de332b.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///./src/components/panels/CameraCv/Index.vue","webpack:///./src/components/panels/CameraCv/Index.vue?fdf8"],"names":["camera-plugin","name","components","Camera","render"],"mappings":"wNACE,eAA6B,GAArBA,gBAAc,O,gBAMT,GACbC,KAAM,WACNC,WAAY,CAACC,OAAA,eCNf,EAAOC,OAASA,EAED","file":"static/js/chunk-2d0da3df.99de332b.js","sourcesContent":["<template>\n <Camera camera-plugin=\"cv\" />\n</template>\n\n<script>\nimport Camera from \"@/components/panels/Camera/Index\";\n\nexport default {\n name: \"CameraCv\",\n components: {Camera},\n}\n</script>\n","import { render } from \"./Index.vue?vue&type=template&id=351194be\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script"],"sourceRoot":""}
|
2
platypush/backend/http/dist/static/js/chunk-2d208116.4f67ac14.js
vendored
Normal file
2
platypush/backend/http/dist/static/js/chunk-2d208116.4f67ac14.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d208116"],{a2e4:function(e,a,n){"use strict";n.r(a);var r=n("7a23");function c(e,a,n,c,t,p){var u=Object(r["z"])("Camera");return Object(r["r"])(),Object(r["e"])(u,{"camera-plugin":"ffmpeg"})}var t=n("1ed9"),p={name:"CameraFfmpeg",components:{Camera:t["default"]}};p.render=c;a["default"]=p}}]);
|
||||
//# sourceMappingURL=chunk-2d208116.4f67ac14.js.map
|
1
platypush/backend/http/dist/static/js/chunk-2d208116.4f67ac14.js.map
vendored
Normal file
1
platypush/backend/http/dist/static/js/chunk-2d208116.4f67ac14.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["webpack:///./src/components/panels/CameraFfmpeg/Index.vue","webpack:///./src/components/panels/CameraFfmpeg/Index.vue?ee79"],"names":["camera-plugin","name","components","Camera","render"],"mappings":"sNACE,eAAiC,GAAzBA,gBAAc,W,gBAMT,GACbC,KAAM,eACNC,WAAY,CAACC,OAAA,eCNf,EAAOC,OAASA,EAED","file":"static/js/chunk-2d208116.4f67ac14.js","sourcesContent":["<template>\n <Camera camera-plugin=\"ffmpeg\" />\n</template>\n\n<script>\nimport Camera from \"@/components/panels/Camera/Index\";\n\nexport default {\n name: \"CameraFfmpeg\",\n components: {Camera},\n}\n</script>\n","import { render } from \"./Index.vue?vue&type=template&id=dd632828\"\nimport script from \"./Index.vue?vue&type=script&lang=js\"\nexport * from \"./Index.vue?vue&type=script&lang=js\"\nscript.render = render\n\nexport default script"],"sourceRoot":""}
|
|
@ -1,5 +1,17 @@
|
|||
{
|
||||
"icons": {
|
||||
"camera.cv": {
|
||||
"class": "fas fa-camera"
|
||||
},
|
||||
"camera.ffmpeg": {
|
||||
"class": "fas fa-camera"
|
||||
},
|
||||
"camera.gstreamer": {
|
||||
"class": "fas fa-camera"
|
||||
},
|
||||
"camera.pi": {
|
||||
"class": "fas fa-camera"
|
||||
},
|
||||
"light.hue": {
|
||||
"class": "fas fa-lightbulb"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
<template>
|
||||
<div class="camera">
|
||||
<div class="camera-container">
|
||||
<div class="frame-container" ref="frameContainer">
|
||||
<div class="no-frame" v-if="!streaming && !capturing && !captured">The camera is not active</div>
|
||||
<img class="frame" :src="url" ref="frame" alt="">
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="left">
|
||||
<button type="button" @click="startStreaming" :disabled="capturing" title="Start video" v-if="!streaming">
|
||||
<i class="fa fa-play" />
|
||||
</button>
|
||||
|
||||
<button type="button" @click="stopStreaming" :disabled="capturing" title="Stop video" v-else>
|
||||
<i class="fa fa-stop" />
|
||||
</button>
|
||||
|
||||
<button type="button" @click="capture" :disabled="streaming || capturing" title="Take a picture">
|
||||
<i class="fas fa-camera" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<button type="button" @click="$refs.paramsModal.show()" title="Settings">
|
||||
<i class="fas fa-cog" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="url" v-if="url?.length">
|
||||
<label class="row">
|
||||
<span class="name">Stream URL</span>
|
||||
<input name="url" type="text" :value="fullURL" disabled="disabled"/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<Modal ref="paramsModal" title="Camera Parameters">
|
||||
<div class="params">
|
||||
<label class="row">
|
||||
<span class="name">Device</span>
|
||||
<input name="device" type="text" v-model="attrs.device" @change="onDeviceChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Width</span>
|
||||
<input name="width" type="text" v-model="attrs.resolution[0]" @change="onSizeChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Height</span>
|
||||
<input name="height" type="text" v-model="attrs.resolution[1]" @change="onSizeChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Horizontal Flip</span>
|
||||
<input name="horizontal_flip" type="checkbox" v-model="attrs.horizontal_flip" @change="onFlipChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Vertical Flip</span>
|
||||
<input name="vertical_flip" type="checkbox" v-model="attrs.vertical_flip" @change="onFlipChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Rotate</span>
|
||||
<input name="rotate" type="text" v-model="attrs.rotate" @change="onSizeChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Scale-X</span>
|
||||
<input name="scale_x" type="text" v-model="attrs.scale_x" @change="onSizeChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Scale-Y</span>
|
||||
<input name="scale_y" type="text" v-model="attrs.scale_y" @change="onSizeChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Frames per second</span>
|
||||
<input name="fps" type="text" v-model="attrs.fps" @change="onFpsChanged"/>
|
||||
</label>
|
||||
|
||||
<label class="row">
|
||||
<span class="name">Grayscale</span>
|
||||
<input name="grayscale" type="checkbox" v-model="attrs.grayscale" @change="onGrayscaleChanged"/>
|
||||
</label>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CameraMixin from "@/components/panels/Camera/Mixin";
|
||||
import Modal from "@/components/Modal";
|
||||
|
||||
export default {
|
||||
name: "Camera",
|
||||
components: {Modal},
|
||||
mixins: [CameraMixin],
|
||||
props: {
|
||||
cameraPlugin: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
fullURL() {
|
||||
return `${window.location.protocol}//${window.location.host}${this.url}`
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
startStreaming() {
|
||||
this._startStreaming(this.cameraPlugin)
|
||||
},
|
||||
|
||||
capture() {
|
||||
this._capture(this.cameraPlugin)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$camera-background: #101520;
|
||||
|
||||
.camera {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $background-color;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 3em;
|
||||
|
||||
.camera-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background: $camera-background;
|
||||
|
||||
.frame-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.frame, .no-frame {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.frame {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.no-frame {
|
||||
display: flex;
|
||||
color: white;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.controls {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
border-top: 1px solid #202530;
|
||||
padding: .5em .25em;
|
||||
|
||||
.left,.right {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
button {
|
||||
background: none;
|
||||
color: white;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
color: $default-hover-fg-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.url {
|
||||
@media screen and (max-width: calc(#{$tablet} - 1px)) {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $tablet) {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
margin: 1em;
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 500px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.params {
|
||||
@media screen and (min-width: $tablet) {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: -2em;
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
label {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
|
||||
.name {
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
.name {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
background: $default-bg-4;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $hover-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
.content {
|
||||
@media screen and (max-width: calc(#{$tablet} - 1px)) {
|
||||
width: 90% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<script>
|
||||
export default {
|
||||
name: "CameraMixin",
|
||||
props: {
|
||||
cameraPlugin: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
streaming: false,
|
||||
capturing: false,
|
||||
captured: false,
|
||||
url: null,
|
||||
attrs: {},
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
params() {
|
||||
return {
|
||||
resolution: this.attrs.resolution,
|
||||
device: this.attrs.device?.length ? this.attrs.device : null,
|
||||
horizontal_flip: parseInt(0 + this.attrs.horizontal_flip),
|
||||
vertical_flip: parseInt(0 + this.attrs.vertical_flip),
|
||||
rotate: parseFloat(this.attrs.rotate),
|
||||
scale_x: parseFloat(this.attrs.scale_x),
|
||||
scale_y: parseFloat(this.attrs.scale_y),
|
||||
fps: parseFloat(this.attrs.fps),
|
||||
grayscale: parseInt(0 + this.attrs.grayscale),
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
getUrl(plugin, action) {
|
||||
return '/camera/' + plugin + '/' + action + '?' +
|
||||
Object.entries(this.params).filter((entry) => entry[1] != null && ('' + entry[1]).length > 0)
|
||||
.map(([k, v]) => k + '=' + v).join('&')
|
||||
},
|
||||
|
||||
_startStreaming(plugin) {
|
||||
if (this.streaming)
|
||||
return
|
||||
|
||||
this.streaming = true
|
||||
this.capturing = false
|
||||
this.captured = false
|
||||
this.url = this.getUrl(plugin, 'video.' + this.attrs.stream_format)
|
||||
},
|
||||
|
||||
stopStreaming() {
|
||||
if (!this.streaming)
|
||||
return
|
||||
|
||||
this.streaming = false
|
||||
this.capturing = false
|
||||
this.url = null
|
||||
},
|
||||
|
||||
_capture(plugin) {
|
||||
if (this.capturing)
|
||||
return
|
||||
|
||||
this.streaming = false
|
||||
this.capturing = true
|
||||
this.captured = true
|
||||
this.url = this.getUrl(plugin, 'photo.jpg') + '&t=' + (new Date()).getTime()
|
||||
},
|
||||
|
||||
onFrameLoaded() {
|
||||
if (this.capturing) {
|
||||
this.capturing = false
|
||||
}
|
||||
},
|
||||
|
||||
onDeviceChanged() {},
|
||||
onFlipChanged() {},
|
||||
onSizeChanged() {
|
||||
const degToRad = (deg) => (deg * Math.PI)/180
|
||||
const rot = degToRad(this.params.rotate)
|
||||
this.$refs.frameContainer.style.width = Math.round(this.params.scale_x * Math.abs(this.params.resolution[0] * Math.cos(rot) + this.params.resolution[1] * Math.sin(rot))) + 'px'
|
||||
this.$refs.frameContainer.style.height = Math.round(this.params.scale_y * Math.abs(this.params.resolution[0] * Math.sin(rot) + this.params.resolution[1] * Math.cos(rot))) + 'px'
|
||||
},
|
||||
|
||||
onFpsChanged() {},
|
||||
onGrayscaleChanged() {},
|
||||
},
|
||||
|
||||
created() {
|
||||
const config = this.$root.config[`camera.${this.cameraPlugin}`] || {}
|
||||
this.attrs = {
|
||||
resolution: config.resolution || [640, 480],
|
||||
device: config.device,
|
||||
horizontal_flip: config.horizontal_flip || 0,
|
||||
vertical_flip: config.vertical_flip || 0,
|
||||
rotate: config.rotate || 0,
|
||||
scale_x: config.scale_x || 1.0,
|
||||
scale_y: config.scale_y || 1.0,
|
||||
fps: config.fps || 16.0,
|
||||
grayscale: config.grayscale || 0,
|
||||
stream_format: config.stream_format || 'mjpeg',
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$refs.frame.addEventListener('load', this.onFrameLoaded)
|
||||
this.onSizeChanged()
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<Camera camera-plugin="cv" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Camera from "@/components/panels/Camera/Index";
|
||||
|
||||
export default {
|
||||
name: "CameraCv",
|
||||
components: {Camera},
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<Camera camera-plugin="ffmpeg" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Camera from "@/components/panels/Camera/Index";
|
||||
|
||||
export default {
|
||||
name: "CameraFfmpeg",
|
||||
components: {Camera},
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<template>
|
||||
<Camera camera-plugin="gstreamer" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Camera from "@/components/panels/Camera/Index";
|
||||
|
||||
export default {
|
||||
name: "CameraGstreamer",
|
||||
components: {Camera},
|
||||
}
|
||||
</script>
|
|
@ -17,15 +17,19 @@ module.exports = {
|
|||
proxy: {
|
||||
'/execute': {
|
||||
target: 'http://localhost:8008',
|
||||
changeOrigin: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
'/auth': {
|
||||
target: 'http://localhost:8008',
|
||||
changeOrigin: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
'/logout': {
|
||||
target: 'http://localhost:8008',
|
||||
changeOrigin: true,
|
||||
changeOrigin: true
|
||||
},
|
||||
'/camera/*': {
|
||||
target: 'http://localhost:8008',
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue