toolshed/frontend/src/components/WebcamFileSource.vue
2024-08-31 01:24:57 +02:00

74 lines
No EOL
2.6 KiB
Vue

<template>
<div class="d-inline-block">
<label @click="show_modal = true">
<slot></slot>
</label>
<div class="modal">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<select v-model="selectedCamera" v-on:change="openStream" class="form-select position-relative w-75 mx-auto mt-4" aria-label="Select Camera Source">
<option disabled value="">Select Camera Source</option>
<option v-for="camera in availableCameras" :key="camera.deviceId" :value="camera">
{{ camera.label }}
</option>
</select>
<video
v-if="capturing"
ref="video"
class="img-fluid rounded mx-auto d-block mb-3 img-preview w-100"
>
Video stream not available.
</video>
<canvas ref="canvas" class="img-fluid d-none img-preview"/>
</div>
</div>
</div>
</div>
</template>
<style scoped>
</style>
<script>
export default {
name: "WebcamFileSource",
data: () => ({
show_modal: false,
availableCameras: [],
selectedCamera: undefined,
capturing: false,
streaming: false,
stream: undefined,
dataImage: undefined
}),
methods: {
async openStream() {
if (!this.capturing) {
this.capturing = true;
this.streaming = false;
this.stream = await navigator.mediaDevices.getUserMedia({video: {deviceId: this.selectedCamera.deviceId}, audio: false});
const {video} = this.$refs;
video.srcObject = this.stream;
video.play();
video.addEventListener('canplay', () => {
this.streaming = true;
}, false);
}
},
async open() {
await navigator.mediaDevices.getUserMedia({video: true});
const devices = await navigator.mediaDevices.enumerateDevices();
this.availableCameras = devices.filter(device => device.kind === "videoinput");
if (this.availableCameras.length === 0) return;
if (this.availableCameras.length === 1) {
this.selectedCamera = this.availableCameras[0];
await this.openStream();
}
}
},
mounted() {
this.open();
}
}
</script>