diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-01-03 00:26:51 +0000 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-01-03 03:42:43 +0000 |
| commit | 864a1d2a22580a33b5e928734fd256c2133fb672 (patch) | |
| tree | f164047133c293ae768112a6aad7eaab5df53401 /hsm-web/Client/src | |
| parent | f7f11acafe0a404fa218c13832e32fce574ae0f6 (diff) | |
Adds camera streaming to frontend
Diffstat (limited to 'hsm-web/Client/src')
| -rw-r--r-- | hsm-web/Client/src/App.vue | 5 | ||||
| -rw-r--r-- | hsm-web/Client/src/CameraStream.vue | 103 | ||||
| -rw-r--r-- | hsm-web/Client/src/INA226.vue | 31 | ||||
| -rw-r--r-- | hsm-web/Client/src/config.js | 2 |
4 files changed, 124 insertions, 17 deletions
diff --git a/hsm-web/Client/src/App.vue b/hsm-web/Client/src/App.vue index 84fefcf..af4ca3e 100644 --- a/hsm-web/Client/src/App.vue +++ b/hsm-web/Client/src/App.vue @@ -1,14 +1,17 @@ <template> <h1>HsMouse</h1> <INA226 /> + <CameraStream /> </template> <script> import INA226 from './INA226.vue' +import CameraStream from './CameraStream.vue' export default { components: { - INA226 + INA226, + CameraStream } } </script> diff --git a/hsm-web/Client/src/CameraStream.vue b/hsm-web/Client/src/CameraStream.vue new file mode 100644 index 0000000..1defed2 --- /dev/null +++ b/hsm-web/Client/src/CameraStream.vue @@ -0,0 +1,103 @@ +<template> + <h2>Camera Stream</h2> + <button @click='toggleStream()' :disabled='disabled'>{{ command }}</button> + <video ref='player' muted></video> +</template> + +<script> +import axios from 'axios' +import config from './config' +import GstWebRTCAPI from '@tomoxv/gstwebrtc-api/src/gstwebrtc-api.js' +import { useTemplateRef } from 'vue' + +export default { + data() { + return { + api: null, + listener: null, + player: null, + session: null, + + command: 'Loading', + disabled: true, + streaming: false + } + }, + mounted() { + this.player = useTemplateRef('player') + this.monitor() + this.bindStream() + }, + methods: { + // Continuously checks if WebRTC stream is running on server + async monitor() { + const res = await axios.get(config.api + '/isStreaming') + + switch (res.status) { + case 200: + this.command = res.data ? 'Stop' : 'Play' + this.disabled = false + this.streaming = res.data + break + default: + this.command = 'Error' + this.disabled = true + this.streaming = false + } + + setTimeout(this.monitor, 1000) + }, + + // Toggles WebRTC stream + async toggleStream() { + const ep = this.streaming ? '/stopStream' : '/startStream' + const res = await axios.get(config.api + ep) + + if (res.status != 200) { + console.error(res) + } + }, + + // Binds WebRTC stream to video element + bindStream() { + this.api = new GstWebRTCAPI({ + meta: { name: 'WebClient-' + Date.now() }, + signalingServerUrl: 'ws://' + window.location.hostname + ':8443' + }) + + this.listener = { + producerAdded: (producer) => { + console.log("Producer added", producer) + + this.session = this.api.createConsumerSession(producer.id) + this.session.addEventListener('streamsChanged', () => { + if (this.session.streams.length > 0) { + this.player.srcObject = this.session.streams[0] + this.player.play() + } + }) + + this.session.connect() + }, + + producerRemoved: (producer) => { + console.log("Producer removed", producer) + + this.player.pause() + this.player.srcObject = null + this.session = null + } + } + + this.api.registerProducersListener(this.listener) + } + } +} +</script> + +<style> +video { + height: 360px; + width: 480px; +} +</style> diff --git a/hsm-web/Client/src/INA226.vue b/hsm-web/Client/src/INA226.vue index bf0141f..a827b0b 100644 --- a/hsm-web/Client/src/INA226.vue +++ b/hsm-web/Client/src/INA226.vue @@ -1,41 +1,42 @@ <template> - <h3>Battery Status</h3> + <h2>Battery Status</h2> <table> <tbody> <tr> - <td>{{ ina226Reading.voltage.toFixed(2) }}V</td> - <td>{{ ina226Reading.current.toFixed(2) }}A</td> - <td>{{ ina226Reading.power.toFixed(2) }}W</td> + <td>{{ fmt(reading.voltage, 'V') }}</td> + <td>{{ fmt(reading.current, 'A') }}</td> + <td>{{ fmt(reading.power, 'W') }}</td> </tr> </tbody> </table> </template> <script> -import axios from 'axios' +import axios from 'axios' import config from './config' export default { data() { return { - ina226Reading: { + reading: { voltage: 0, current: 0, - power: 0 + power: 0 } } }, mounted() { - this.getINA226Reading() + this.getReading() }, methods: { - getINA226Reading() { - axios - .get(`${config.api}/ina226`) - .then(res => { - this.ina226Reading = res.data - setTimeout(this.getINA226Reading, 1000) - }) + async getReading() { + const res = await axios.get(config.api + '/ina226') + this.reading = res.data + + setTimeout(this.getReading, 1000) + }, + fmt(val, sfx) { + return val.toFixed(2) + sfx } } } diff --git a/hsm-web/Client/src/config.js b/hsm-web/Client/src/config.js index b8e9a98..b2217b7 100644 --- a/hsm-web/Client/src/config.js +++ b/hsm-web/Client/src/config.js @@ -1,3 +1,3 @@ module.exports = { - api: 'http://192.168.8.170:3000' + api: `http://${window.location.hostname}:3000` } |
