mirror of
https://github.com/ad1217/PrinterStatus
synced 2024-12-25 11:05:41 -05:00
Handle camera transforms in ffmpeg, rather than client side
This simplifies the client, as well as fixing rotation
This commit is contained in:
parent
cc0f6d90d0
commit
afe6a1aed5
@ -40,18 +40,13 @@ export default class OctoprintConnection {
|
||||
const webcamURL = new URL(settings.webcam.streamUrl, this.address);
|
||||
// TODO: handle recreating proxy on URL change
|
||||
if (this.webcamStream === undefined) {
|
||||
this.webcamStream = make_mp4frag(this.slug, webcamURL);
|
||||
this.webcamStream = make_mp4frag(this.slug, webcamURL, settings.webcam);
|
||||
}
|
||||
this.settingsMessage = {
|
||||
kind: "settings",
|
||||
printer: this.slug,
|
||||
name: settings.appearance.name,
|
||||
color: settings.appearance.color,
|
||||
webcam: {
|
||||
flipH: settings.webcam.flipH,
|
||||
flipV: settings.webcam.flipV,
|
||||
rotate90: settings.webcam.rotate90,
|
||||
}
|
||||
}
|
||||
this.broadcast(this.settingsMessage);
|
||||
|
||||
|
@ -1,7 +1,29 @@
|
||||
import * as ffmpeg from 'fluent-ffmpeg';
|
||||
import * as Mp4Frag from 'mp4frag';
|
||||
|
||||
export function make_mp4frag(slug: string, url: URL | string): Mp4Frag {
|
||||
interface WebcamSettings {
|
||||
flipH: boolean;
|
||||
flipV: boolean;
|
||||
rotate90: boolean;
|
||||
}
|
||||
|
||||
export function make_mp4frag(
|
||||
slug: string,
|
||||
url: URL | string,
|
||||
webcamSettings: WebcamSettings
|
||||
): Mp4Frag {
|
||||
let transforms = [];
|
||||
if (webcamSettings.flipH) {
|
||||
transforms.push('hflip');
|
||||
}
|
||||
if (webcamSettings.flipV) {
|
||||
transforms.push('vflip');
|
||||
}
|
||||
if (webcamSettings.rotate90) {
|
||||
transforms.push('transpose=2');
|
||||
}
|
||||
console.log(transforms);
|
||||
|
||||
const command = ffmpeg(url.toString())
|
||||
.nativeFramerate()
|
||||
.inputOptions([
|
||||
@ -12,7 +34,9 @@ export function make_mp4frag(slug: string, url: URL | string): Mp4Frag {
|
||||
.noAudio()
|
||||
.videoCodec('libx264')
|
||||
.size('640x480')
|
||||
.autopad()
|
||||
.videoFilter('hqdn3d')
|
||||
.videoFilters(transforms)
|
||||
.format('mp4')
|
||||
.outputOptions([
|
||||
'-tune zerolatency',
|
||||
|
@ -29,7 +29,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, Ref } from 'vue';
|
||||
|
||||
import { Message, WebcamSettings } from '../types/messages';
|
||||
import { Message } from '../types/messages';
|
||||
import PrinterCard, { PrinterInfo } from './PrinterCard.vue';
|
||||
|
||||
const printers: Ref<{ [key: string]: PrinterInfo }> = ref({});
|
||||
@ -52,7 +52,6 @@ function connectWebsocket() {
|
||||
if (!(event.printer in printers.value)) {
|
||||
printers.value[event.printer] = {
|
||||
status: null,
|
||||
webcam: null,
|
||||
color: null,
|
||||
lastUpdate: new Date(),
|
||||
};
|
||||
@ -61,7 +60,6 @@ function connectWebsocket() {
|
||||
|
||||
if (event.kind === 'settings') {
|
||||
printers.value[event.printer].name = event.name;
|
||||
printers.value[event.printer].webcam = event.webcam;
|
||||
printers.value[event.printer].color = event.color;
|
||||
} else if (event.kind === 'status') {
|
||||
if ('current' in event.msg && event.msg.current) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
muted
|
||||
class="card-img webcam"
|
||||
ref="video"
|
||||
:style="webcamTransform"
|
||||
></video>
|
||||
<div class="card-body" v-if="status">
|
||||
<div>{{ status.state.text }}</div>
|
||||
@ -54,7 +53,7 @@ import { computed, onMounted, Ref, ref, watchEffect } from 'vue';
|
||||
import prettyMilliseconds from 'pretty-ms';
|
||||
|
||||
import { CurrentOrHistoryPayload } from '../types/octoprint';
|
||||
import { WebcamSettings, OctoprintColor } from '../types/messages';
|
||||
import { OctoprintColor } from '../types/messages';
|
||||
|
||||
interface Props {
|
||||
slug: string;
|
||||
@ -62,7 +61,6 @@ interface Props {
|
||||
lastUpdate: Date;
|
||||
now: Date;
|
||||
status: CurrentOrHistoryPayload | null;
|
||||
webcam: WebcamSettings | null;
|
||||
color: OctoprintColor | null;
|
||||
}
|
||||
|
||||
@ -116,24 +114,6 @@ const lastUpdateString = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const webcamTransform = computed(() => {
|
||||
if (props.webcam) {
|
||||
const transforms = [];
|
||||
if (props.webcam.flipH) {
|
||||
transforms.push('scaleX(-1)');
|
||||
}
|
||||
if (props.webcam.flipV) {
|
||||
transforms.push('scaleY(-1)');
|
||||
}
|
||||
if (props.webcam.rotate90) {
|
||||
transforms.push('rotate(90)');
|
||||
}
|
||||
return { transform: transforms.join(' ') };
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
console.log(video.value, hls.value);
|
||||
if (hls.value && video.value) {
|
||||
@ -171,4 +151,8 @@ $bs-colors: ('red', 'orange', 'yellow', 'green', 'blue', 'white');
|
||||
color: var(--bs-light);
|
||||
}
|
||||
}
|
||||
|
||||
.webcam {
|
||||
background-color: black;
|
||||
}
|
||||
</style>
|
||||
|
7
types/messages.d.ts
vendored
7
types/messages.d.ts
vendored
@ -9,18 +9,11 @@ export interface StatusMessage extends BaseMessage {
|
||||
msg: OctoprintMessage;
|
||||
}
|
||||
|
||||
export interface WebcamSettings {
|
||||
flipH: boolean;
|
||||
flipV: boolean;
|
||||
rotate90: boolean;
|
||||
}
|
||||
|
||||
export type OctoprintColor = 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'violet' | 'black' | 'white' | 'default';
|
||||
|
||||
export interface SettingsMessage extends BaseMessage {
|
||||
kind: 'settings';
|
||||
name: string;
|
||||
webcam: WebcamSettings;
|
||||
color: OctoprintColor;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user