feat: max webcam height to fit on the screen (#1246)

This commit is contained in:
Stefan Dej 2023-02-18 15:04:10 +01:00 committed by GitHub
parent 92438bf8a7
commit 43dc843eca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 65 deletions

View File

@ -6,7 +6,8 @@
:icon="mdiWebcam"
:title="$t('Panels.WebcamPanel.Headline')"
:collapsible="$route.fullPath !== '/cam'"
card-class="webcam-panel">
card-class="webcam-panel"
:margin-bottom="currentPage !== 'page'">
<template v-if="webcams.length > 1" #buttons>
<v-menu :offset-y="true" title="Webcam">
<template #activator="{ on, attrs }">

View File

@ -1,11 +1,13 @@
<template>
<video
ref="video"
v-observe-visibility="visibilityChanged"
autoplay
muted
:style="webcamStyle"
class="webcamImage" />
<div class="d-flex justify-center">
<video
ref="video"
v-observe-visibility="visibilityChanged"
autoplay
muted
:style="webcamStyle"
class="webcamImage" />
</div>
</template>
<script lang="ts">
@ -15,6 +17,7 @@ import Hls from 'hls.js'
@Component
export default class Hlsstreamer extends Mixins(BaseMixin) {
private aspectRatio: null | number = null
private isVisible = true
private hls: Hls | null = null
@ -35,12 +38,24 @@ export default class Hlsstreamer extends Mixins(BaseMixin) {
}
get webcamStyle() {
const output = {
transform: 'none',
aspectRatio: 16 / 9,
maxHeight: window.innerHeight - 155 + 'px',
maxWidth: 'auto',
}
let transforms = ''
if ('flipX' in this.camSettings && this.camSettings.flipX) transforms += ' scaleX(-1)'
if ('flipX' in this.camSettings && this.camSettings.flipY) transforms += ' scaleY(-1)'
if (transforms.trimStart().length) return { transform: transforms.trimStart() }
return ''
if (this.aspectRatio) {
output.aspectRatio = this.aspectRatio
output.maxWidth = (window.innerHeight - 155) * this.aspectRatio + 'px'
}
return output
}
visibilityChanged(isVisible: boolean) {
@ -49,6 +64,11 @@ export default class Hlsstreamer extends Mixins(BaseMixin) {
mounted() {
this.play()
const video = this.$refs.video
video.onplaying = () => {
this.aspectRatio = video.videoWidth / video.videoHeight
}
}
updated() {

View File

@ -1,22 +1,5 @@
<style scoped>
.webcamImage {
width: 100%;
background: lightgray;
}
.webcamFpsOutput {
display: inline-block;
position: absolute;
bottom: 6px;
right: 0;
background: rgba(0, 0, 0, 0.8);
padding: 3px 10px;
border-top-left-radius: 5px;
}
</style>
<template>
<div style="position: relative">
<div style="position: relative" class="d-flex justify-center">
<img
ref="image"
v-observe-visibility="viewportVisibilityChanged"
@ -40,8 +23,10 @@ export default class Mjpegstreamer extends Mixins(BaseMixin) {
private currentFPS = 0
private streamState = false
private aspectRatio: null | number = null
private timerFPS: number | null = null
private timerRestart: number | null = null
// eslint-disable-next-line no-undef
private timerFPS: NodeJS.Timeout | null = null
// eslint-disable-next-line no-undef
private timerRestart: NodeJS.Timeout | null = null
private stream: ReadableStream | null = null
private controller: AbortController | null = null
private isVisibleViewport = false
@ -72,6 +57,8 @@ export default class Mjpegstreamer extends Mixins(BaseMixin) {
const output = {
transform: 'none',
aspectRatio: 16 / 9,
maxHeight: window.innerHeight - 155 + 'px',
maxWidth: 'auto',
}
let transforms = ''
@ -79,7 +66,10 @@ export default class Mjpegstreamer extends Mixins(BaseMixin) {
if ('flipX' in this.camSettings && this.camSettings.flipY) transforms += ' scaleY(-1)'
if (transforms.trimStart().length) output.transform = transforms.trimStart()
if (this.aspectRatio) output.aspectRatio = this.aspectRatio
if (this.aspectRatio) {
output.aspectRatio = this.aspectRatio
output.maxWidth = (window.innerHeight - 155) * this.aspectRatio + 'px'
}
return output
}
@ -252,3 +242,20 @@ export default class Mjpegstreamer extends Mixins(BaseMixin) {
}
}
</script>
<style scoped>
.webcamImage {
width: 100%;
background: lightgray;
}
.webcamFpsOutput {
display: inline-block;
position: absolute;
bottom: 6px;
right: 0;
background: rgba(0, 0, 0, 0.8);
padding: 3px 10px;
border-top-left-radius: 5px;
}
</style>

View File

@ -1,21 +1,5 @@
<style scoped>
.webcamImage {
width: 100%;
}
.webcamFpsOutput {
display: inline-block;
position: absolute;
bottom: 6px;
right: 0;
background: rgba(0, 0, 0, 0.8);
padding: 3px 10px;
border-top-left-radius: 5px;
}
</style>
<template>
<div style="position: relative">
<div style="position: relative" class="d-flex justify-center">
<div v-if="!isLoaded" class="text-center py-5">
<v-progress-circular indeterminate color="primary"></v-progress-circular>
</div>
@ -44,7 +28,8 @@ export default class MjpegstreamerAdaptive extends Mixins(BaseMixin) {
private isVisibleDocument = true
private isVisibleViewport = false
private isLoaded = true
private timer: number | undefined = undefined
// eslint-disable-next-line no-undef
private timer: NodeJS.Timeout | undefined = undefined
private request_start_time = performance.now()
private start_time = performance.now()
@ -67,6 +52,8 @@ export default class MjpegstreamerAdaptive extends Mixins(BaseMixin) {
const output = {
transform: 'none',
aspectRatio: 16 / 9,
maxHeight: window.innerHeight - 155 + 'px',
maxWidth: 'auto',
}
let transforms = ''
@ -75,7 +62,10 @@ export default class MjpegstreamerAdaptive extends Mixins(BaseMixin) {
if ((this.camSettings.rotate ?? 0) === 180) transforms += ' rotate(180deg)'
if (transforms.trimStart().length) output.transform = transforms.trimStart()
if (this.aspectRatio) output.aspectRatio = this.aspectRatio
if (this.aspectRatio) {
output.aspectRatio = this.aspectRatio
output.maxWidth = (window.innerHeight - 155) * this.aspectRatio + 'px'
}
return output
}
@ -114,10 +104,10 @@ export default class MjpegstreamerAdaptive extends Mixins(BaseMixin) {
canvas.width = canvas.clientWidth
if (this.rotate) {
if (this.aspectRatio === null) this.aspectRatio = frame.height / frame.width
canvas.height = canvas.clientWidth / (frame.height / frame.width)
canvas.height = canvas.clientWidth / this.aspectRatio
} else {
if (this.aspectRatio === null) this.aspectRatio = frame.width / frame.height
canvas.height = canvas.clientWidth * (frame.width / frame.height)
canvas.height = canvas.clientWidth * this.aspectRatio
}
if (this.rotate) {
@ -223,3 +213,19 @@ export default class MjpegstreamerAdaptive extends Mixins(BaseMixin) {
}
}
</script>
<style scoped>
.webcamImage {
width: 100%;
}
.webcamFpsOutput {
display: inline-block;
position: absolute;
bottom: 6px;
right: 0;
background: rgba(0, 0, 0, 0.8);
padding: 3px 10px;
border-top-left-radius: 5px;
}
</style>

View File

@ -1,17 +1,12 @@
<style scoped>
.webcamImage {
width: 100%;
background: lightgray;
}
</style>
<template>
<img
ref="webcamUv4lMjpegImage"
v-observe-visibility="viewportVisibilityChanged"
:style="webcamStyle"
class="webcamImage"
@load="onload" />
<div class="d-flex justify-center">
<img
ref="webcamUv4lMjpegImage"
v-observe-visibility="viewportVisibilityChanged"
:style="webcamStyle"
class="webcamImage"
@load="onload" />
</div>
</template>
<script lang="ts">
@ -45,6 +40,8 @@ export default class Uv4lMjpeg extends Mixins(BaseMixin) {
const output = {
transform: 'none',
aspectRatio: 16 / 9,
maxHeight: window.innerHeight - 155 + 'px',
maxWidth: 'auto',
}
let transforms = ''
@ -52,7 +49,10 @@ export default class Uv4lMjpeg extends Mixins(BaseMixin) {
if ('flipX' in this.camSettings && this.camSettings.flipY) transforms += ' scaleY(-1)'
if (transforms.trimStart().length) output.transform = transforms.trimStart()
if (this.aspectRatio) output.aspectRatio = this.aspectRatio
if (this.aspectRatio) {
output.aspectRatio = this.aspectRatio
output.maxWidth = (window.innerHeight - 155) * this.aspectRatio + 'px'
}
return output
}
@ -116,3 +116,10 @@ export default class Uv4lMjpeg extends Mixins(BaseMixin) {
}
}
</script>
<style scoped>
.webcamImage {
width: 100%;
background: lightgray;
}
</style>