forked from platypush/platypush
134 lines
3.6 KiB
Vue
134 lines
3.6 KiB
Vue
<script>
|
|
import Utils from "@/Utils";
|
|
|
|
export default {
|
|
name: "CameraMixin",
|
|
mixins: [Utils],
|
|
|
|
props: {
|
|
cameraPlugin: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
streaming: false,
|
|
capturing: false,
|
|
captured: false,
|
|
audioOn: 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() {},
|
|
|
|
startAudio() {
|
|
this.audioOn = true
|
|
},
|
|
|
|
async stopAudio() {
|
|
this.audioOn = false
|
|
await this.request('sound.stop_recording')
|
|
},
|
|
},
|
|
|
|
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()
|
|
this.$watch(() => this.attrs.resolution, this.onSizeChanged)
|
|
this.$watch(() => this.attrs.horizontal_flip, this.onSizeChanged)
|
|
this.$watch(() => this.attrs.vertical_flip, this.onSizeChanged)
|
|
this.$watch(() => this.attrs.rotate, this.onSizeChanged)
|
|
this.$watch(() => this.attrs.scale_x, this.onSizeChanged)
|
|
this.$watch(() => this.attrs.scale_y, this.onSizeChanged)
|
|
},
|
|
}
|
|
</script>
|