Display now properly calculates position for displaying images. Move towards a send-everything-to-every-client broadcast model for the server

This commit is contained in:
Matt McWilliams 2024-08-14 22:43:02 -04:00
parent d3f0a27f30
commit 6a8946149c
21 changed files with 198 additions and 53 deletions

View File

@ -8,6 +8,7 @@ class Client {
this.progress = document.getElementById('progress') as HTMLProgressElement; this.progress = document.getElementById('progress') as HTMLProgressElement;
this.client = new WebSocket(uri); this.client = new WebSocket(uri);
this.client.onopen = this.onOpen.bind(this); this.client.onopen = this.onOpen.bind(this);
this.client.onclose = this.onClose.bind(this);
this.client.onmessage = this.onMessage.bind(this); this.client.onmessage = this.onMessage.bind(this);
} }
@ -23,6 +24,13 @@ class Client {
private onOpen (event : any) { private onOpen (event : any) {
console.log('Connected'); console.log('Connected');
this.connected = true; this.connected = true;
this.active();
}
private onClose (event : any) {
console.log('Disconnected');
this.connected = false;
this.inactive();
} }
private setSequence(sequence : SequenceState) { private setSequence(sequence : SequenceState) {
@ -96,7 +104,8 @@ class Client {
private receiveSelect (msg : Message) { private receiveSelect (msg : Message) {
console.log('got select'); console.log('got select');
console.dir(msg) console.dir(msg);
(document.getElementById('sequence') as HTMLSelectElement ).value = msg.sequence;
} }
public fullscreen () { public fullscreen () {
@ -113,7 +122,12 @@ class Client {
} }
} }
private active () {
document.getElementById('overlay').classList.add('active');
}
private inactive () {
document.getElementById('overlay').classList.remove('active');
}
} }
const client : Client = new Client(); const client : Client = new Client();

View File

@ -1,4 +1,10 @@
import type { fdOutgoingPosition } from '../fd'; import type { fdOutgoingPosition } from '../fd';
declare class Dimensions {
width: number;
height: number;
constructor(width: number, height: number);
getRatio(): number;
}
export declare class Display { export declare class Display {
private screen; private screen;
private source; private source;
@ -9,4 +15,6 @@ export declare class Display {
setOffsetY(y: number): void; setOffsetY(y: number): void;
setSource(width: number, height: number): void; setSource(width: number, height: number): void;
getDimensions(): fdOutgoingPosition; getDimensions(): fdOutgoingPosition;
getScreen(): Dimensions;
} }
export type { Dimensions };

13
dist/display/index.js vendored
View File

@ -22,14 +22,18 @@ class Display {
this.offset.y = y; this.offset.y = y;
} }
setSource(width, height) { setSource(width, height) {
let offset;
this.source = new Dimensions(width, height); this.source = new Dimensions(width, height);
if (this.source.getRatio() > this.screen.getRatio()) { if (this.source.getRatio() > this.screen.getRatio()) {
this.display = new Dimensions(this.source.getRatio() * this.screen.height, this.screen.height); this.display = new Dimensions(this.screen.width, Math.floor(this.source.width / this.source.getRatio()));
offset = this.screen.height - this.display.height;
this.offset = { x: 0, y: Math.round(offset / 2) };
} }
else { else {
this.display = new Dimensions(this.screen.width, this.source.width / this.source.getRatio()); this.display = new Dimensions(Math.floor(this.source.getRatio() * this.screen.height), this.screen.height);
offset = this.screen.width - this.display.width;
this.offset = { x: Math.round(offset / 2), y: 0 };
} }
this.offset = { x: Math.round(this.display.width), y: 0 };
} }
getDimensions() { getDimensions() {
return { return {
@ -39,6 +43,9 @@ class Display {
y: this.offset.y y: this.offset.y
}; };
} }
getScreen() {
return this.screen;
}
} }
exports.Display = Display; exports.Display = Display;
module.exports = { Display }; module.exports = { Display };

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,UAAU;IAIf,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;CACD;AAOD,MAAa,OAAO;IAQnB,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAE,CAAA;IAC9B,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,SAAS,CAAE,KAAc,EAAE,MAAe;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAChG,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAG,CAAC,EAAG,CAAC,EAAE,CAAA;IAC5D,CAAC;IAEM,aAAa;QACnB,OAAO;YACN,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YACtB,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YACvB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACjB,CAAA;IACF,CAAC;CACD;AAvCD,0BAuCC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,UAAU;IAIf,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;CACD;AAOD,MAAa,OAAO;IAQnB,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAE,CAAA;IAC9B,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,SAAS,CAAE,KAAc,EAAE,MAAe;QAChD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACzG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAClD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3G,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAChD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAG,CAAC,EAAG,CAAC,EAAE,CAAC;QACrD,CAAC;IACF,CAAC;IAEM,aAAa;QACnB,OAAO;YACN,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YACtB,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YACvB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACjB,CAAA;IACF,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AA/CD,0BA+CC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC"}

View File

@ -1,4 +1,12 @@
/** @module lib/ffprobe */ /** @module lib/ffprobe */
interface VideoInfo {
width: number;
height: number;
fps?: number;
seconds?: number;
streams?: any[];
format?: any;
}
/** /**
* Class representing all ffprobe features. * Class representing all ffprobe features.
*/ */
@ -18,7 +26,7 @@ export declare class FFPROBE {
* *
* @returns {object} Video info in an object * @returns {object} Video info in an object
**/ **/
info(video: string): Promise<any>; info(video: string): Promise<VideoInfo>;
private exec; private exec;
/** /**
* Count the number of frames in the video using one of two methods. * Count the number of frames in the video using one of two methods.
@ -31,3 +39,4 @@ export declare class FFPROBE {
**/ **/
frames(video: string): Promise<any>; frames(video: string): Promise<any>;
} }
export type { VideoInfo };

View File

@ -5,7 +5,6 @@ const promises_1 = require("fs/promises");
const path_1 = require("path"); const path_1 = require("path");
const shell_1 = require("../shell"); const shell_1 = require("../shell");
const log_1 = require("../log"); const log_1 = require("../log");
/** @module lib/ffprobe */
/** /**
* Class representing all ffprobe features. * Class representing all ffprobe features.
*/ */
@ -66,14 +65,14 @@ class FFPROBE {
} }
if (!fileExists) { if (!fileExists) {
this.log.error(new Error(`File ${video} does not exist`)); this.log.error(new Error(`File ${video} does not exist`));
return false; return null;
} }
try { try {
raw = await this.exec(cmd); raw = await this.exec(cmd);
} }
catch (err) { catch (err) {
this.log.error('Error getting info', err); this.log.error('Error getting info', err);
return false; return null;
} }
try { try {
json = JSON.parse(raw); json = JSON.parse(raw);

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ffprobe/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ffprobe/index.ts"],"names":[],"mappings":"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"}

29
dist/index.js vendored
View File

@ -132,7 +132,11 @@ async function settings() {
} }
else { else {
wsPort = parseInt(process.env['WS_PORT']); wsPort = parseInt(process.env['WS_PORT']);
log.info(`WS_PORT=${port}`); log.info(`WS_PORT=${wsPort}`);
}
if (wsPort === port) {
log.error(`Websocket port (${wsPort}) should not be the same as HTTP port (${port})`);
process.exit(7);
} }
if (typeof process.env['SEQUENCES'] === 'undefined') { if (typeof process.env['SEQUENCES'] === 'undefined') {
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env'); log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
@ -172,7 +176,6 @@ function onWssConnection(ws, req) {
} }
async function onClientMessage(data, ws) { async function onClientMessage(data, ws) {
let msg = null; let msg = null;
let res = {};
try { try {
msg = JSON.parse(data); msg = JSON.parse(data);
} }
@ -180,38 +183,48 @@ async function onClientMessage(data, ws) {
log.error('Error parsing message', err); log.error('Error parsing message', err);
} }
if (msg !== null && typeof msg.cmd !== 'undefined') { if (msg !== null && typeof msg.cmd !== 'undefined') {
res = await cmd(msg); await cmd(msg);
} }
ws.send(JSON.stringify(res));
} }
async function cmd(msg) { async function cmd(msg) {
let success = false;
switch (msg.cmd) { switch (msg.cmd) {
case 'open': case 'open':
await cameraOpen(); await cameraOpen();
return { cmd: 'open' }; break;
case 'close': case 'close':
await cameraClose(); await cameraClose();
return { cmd: 'close' }; break;
case 'select': case 'select':
await select(msg.sequence); await select(msg.sequence);
return { cmd: 'select', sequence: msg.sequence }; break;
default: default:
log.warn(`No matching command: ${msg.cmd}`); log.warn(`No matching command: ${msg.cmd}`);
} }
} }
async function cameraOpen() { async function cameraOpen() {
await camera.open(); await camera.open();
send({ cmd: 'open' });
} }
async function cameraClose() { async function cameraClose() {
await camera.close(); await camera.close();
send({ cmd: 'close' });
} }
async function select(id) { async function select(id) {
const sequencesArr = await files_1.Files.enumerateSequences(sequences); const sequencesArr = await files_1.Files.enumerateSequences(sequences);
const seq = sequencesArr.find(el => el.hash === id); const seq = sequencesArr.find(el => el.hash === id);
if (typeof seq == 'undefined' || seq == null) { if (typeof seq == 'undefined' || seq == null) {
log.error('Sequence not found, maybe deleted?', new Error(`Cannot find sequence ${id}`)); log.error('Sequence not found, maybe deleted?', new Error(`Cannot find sequence ${id}`));
return false;
} }
await sequence.load(seq); await sequence.load(seq);
return true;
}
async function send(msg) {
const msgStr = JSON.stringify(msg);
wss.clients.forEach((client) => {
client.send(msgStr);
});
} }
app.get('/', async (req, res, next) => { app.get('/', async (req, res, next) => {
const sequencesArr = await files_1.Files.enumerateSequences(sequences); const sequencesArr = await files_1.Files.enumerateSequences(sequences);
@ -227,7 +240,6 @@ async function main() {
camera = new camera_1.Camera(); camera = new camera_1.Camera();
display = new display_1.Display(width, height); display = new display_1.Display(width, height);
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT'])); //fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
sequence = new sequence_1.Sequence(camera, fd, display, ffprobe);
app.listen(port, async () => { app.listen(port, async () => {
log.info(`filmout_manager HTTP server running on port ${port}`); log.info(`filmout_manager HTTP server running on port ${port}`);
}); });
@ -236,6 +248,7 @@ async function main() {
log.info(`filmout_manager WebSocket server running on port ${wsPort}`); log.info(`filmout_manager WebSocket server running on port ${wsPort}`);
//ffmpeg.listFormats(); //ffmpeg.listFormats();
//log.info(await TestImage.Focus(640, 480)); //log.info(await TestImage.Focus(640, 480));
sequence = new sequence_1.Sequence(camera, fd, display, ffprobe, send);
} }
main(); main();
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@ import type { FFPROBE } from '../ffprobe';
export declare class Sequence { export declare class Sequence {
private log; private log;
private current; private current;
private info;
private images; private images;
private camera; private camera;
private display; private display;
@ -14,7 +15,8 @@ export declare class Sequence {
private running; private running;
private progress; private progress;
private frames; private frames;
constructor(camera: Camera, fd: FD, display: Display, ffprobe: FFPROBE); private send;
constructor(camera: Camera, fd: FD, display: Display, ffprobe: FFPROBE, send: Function);
start(): void; start(): void;
stop(): void; stop(): void;
isRunning(): boolean; isRunning(): boolean;

View File

@ -4,14 +4,16 @@ exports.Sequence = void 0;
const files_1 = require("../files"); const files_1 = require("../files");
const log_1 = require("../log"); const log_1 = require("../log");
class Sequence { class Sequence {
constructor(camera, fd, display, ffprobe) { constructor(camera, fd, display, ffprobe, send) {
this.current = null; this.current = null;
this.info = null;
this.images = []; this.images = [];
this.log = (0, log_1.createLog)('seq'); this.log = (0, log_1.createLog)('seq');
this.camera = camera; this.camera = camera;
this.fd = fd; this.fd = fd;
this.display = display; this.display = display;
this.ffprobe = ffprobe; this.ffprobe = ffprobe;
this.send = send;
} }
start() { start() {
this.running = true; this.running = true;
@ -25,8 +27,10 @@ class Sequence {
load(seq) { load(seq) {
this.current = seq; this.current = seq;
this.enumerate(); this.enumerate();
this.send({ cmd: 'select', sequence: seq.hash });
} }
async enumerate() { async enumerate() {
let screen;
if (this.current === null) { if (this.current === null) {
this.log.error('Cannot enumerate sequence because it is not set'); this.log.error('Cannot enumerate sequence because it is not set');
return; return;
@ -40,11 +44,19 @@ class Sequence {
} }
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`); this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
if (this.images.length > 0) { if (this.images.length > 0) {
console.dir(await this.ffprobe.info(this.images[0].path)); this.info = await this.ffprobe.info(this.images[0].path);
}
if (this.info !== null) {
screen = this.display.getScreen();
this.log.info(`Screen: ${screen.width},${screen.height}`);
this.log.info(`Sequence : ${this.info.width},${this.info.height}`);
this.display.setSource(this.info.width, this.info.height);
this.log.info(`Display : ${JSON.stringify(this.display.getDimensions())}`);
} }
} }
unload() { unload() {
this.current = null; this.current = null;
this.info = null;
this.images = []; this.images = [];
} }
getState() { getState() {

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":";;;AAAA,oCAAiC;AACjC,gCAAkC;AAQlC,MAAa,QAAQ;IAYpB,YAAa,MAAe,EAAE,EAAO,EAAE,OAAgB,EAAE,OAAiB;QAVlE,YAAO,GAAoB,IAAI,CAAC;QAChC,WAAM,GAAmB,EAAE,CAAC;QAUnC,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAEM,KAAK;QACX,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACrB,CAAC;IAEM,IAAI;QACV,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAEM,IAAI,CAAE,GAAoB;QAChC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;QACnB,IAAI,CAAC,SAAS,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,SAAS;QACtB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAG,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YAClE,OAAO;QACR,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,CAAC,MAAM,GAAG,MAAM,aAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yCAAyC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;YAClF,OAAO;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,IAAI,aAAa,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAE1H,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3D,CAAC;IACF,CAAC;IAEM,MAAM;QACZ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IAClB,CAAC;IAEM,QAAQ;QACd,OAAO;YACN,IAAI,EAAG,IAAI,CAAC,OAAO,CAAC,IAAI;YACxB,IAAI,EAAG,IAAI,CAAC,OAAO,CAAC,IAAI;YACxB,QAAQ,EAAG,IAAI,CAAC,QAAQ;SACxB,CAAA;IACF,CAAC;CACD;AArED,4BAqEC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"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"}

View File

@ -41,13 +41,17 @@ export class Display {
} }
public setSource (width : number, height : number) { public setSource (width : number, height : number) {
let offset : number;
this.source = new Dimensions(width, height); this.source = new Dimensions(width, height);
if (this.source.getRatio() > this.screen.getRatio()) { if (this.source.getRatio() > this.screen.getRatio()) {
this.display = new Dimensions(this.source.getRatio() * this.screen.height, this.screen.height); this.display = new Dimensions(this.screen.width, Math.floor(this.source.width / this.source.getRatio()));
offset = this.screen.height - this.display.height;
this.offset = { x: 0, y : Math.round(offset / 2) };
} else { } else {
this.display = new Dimensions(this.screen.width, this.source.width / this.source.getRatio()); this.display = new Dimensions(Math.floor(this.source.getRatio() * this.screen.height), this.screen.height);
offset = this.screen.width - this.display.width;
this.offset = { x: Math.round(offset / 2), y : 0 };
} }
this.offset = { x: Math.round(this.display.width), y : 0 }
} }
public getDimensions () : fdOutgoingPosition { public getDimensions () : fdOutgoingPosition {
@ -58,6 +62,11 @@ export class Display {
y : this.offset.y y : this.offset.y
} }
} }
public getScreen () : Dimensions {
return this.screen;
}
} }
module.exports = { Display }; module.exports = { Display };
export type { Dimensions };

View File

@ -8,6 +8,16 @@ import type { Logger } from 'winston';
/** @module lib/ffprobe */ /** @module lib/ffprobe */
interface VideoInfo {
width : number;
height : number;
fps? : number;
seconds? : number;
streams? : any[]; //flesh out if needed
format? : any;
}
/** /**
* Class representing all ffprobe features. * Class representing all ffprobe features.
*/ */
@ -33,7 +43,7 @@ export class FFPROBE {
/** /**
* Parse the fps entry into a float representing the fps of a video * Parse the fps entry into a float representing the fps of a video
**/ **/
private parseFps (fpsStr : string) { private parseFps (fpsStr : string) : number {
let fps : number = 30.0; let fps : number = 30.0;
let parts : string[]; let parts : string[];
if (fpsStr.indexOf('/') !== -1) { if (fpsStr.indexOf('/') !== -1) {
@ -42,7 +52,7 @@ export class FFPROBE {
} else { } else {
fps = parseFloat(fpsStr); fps = parseFloat(fpsStr);
} }
return fps return fps;
} }
/** /**
* Get info on a video in json format. Use for filmout. * Get info on a video in json format. Use for filmout.
@ -51,7 +61,7 @@ export class FFPROBE {
* *
* @returns {object} Video info in an object * @returns {object} Video info in an object
**/ **/
public async info (video : string) { public async info (video : string) : Promise<VideoInfo> {
const cmd : string[] = [ const cmd : string[] = [
this.bin, this.bin,
'-v', 'quiet', '-v', 'quiet',
@ -62,7 +72,7 @@ export class FFPROBE {
]; ];
let fileExists : boolean; let fileExists : boolean;
let raw : any; let raw : any;
let json : any; let json : VideoInfo;
let vid : any; //whether video has stream with video data let vid : any; //whether video has stream with video data
try { try {
@ -72,18 +82,18 @@ export class FFPROBE {
} }
if (!fileExists) { if (!fileExists) {
this.log.error(new Error(`File ${video} does not exist`)); this.log.error(new Error(`File ${video} does not exist`));
return false return null
} }
try { try {
raw = await this.exec(cmd); raw = await this.exec(cmd);
} catch (err) { } catch (err) {
this.log.error('Error getting info', err); this.log.error('Error getting info', err);
return false return null
} }
try { try {
json = JSON.parse(raw); json = JSON.parse(raw) as VideoInfo;
} catch (err) { } catch (err) {
this.log.error('Error parsing stdout', err); this.log.error('Error parsing stdout', err);
this.log.error(raw); this.log.error(raw);
@ -190,3 +200,4 @@ function map (obj : any) {
*/ */
module.exports = { FFPROBE }; module.exports = { FFPROBE };
export type { VideoInfo };

View File

@ -122,8 +122,13 @@ async function settings () {
process.exit(6); process.exit(6);
} else { } else {
wsPort = parseInt(process.env['WS_PORT']); wsPort = parseInt(process.env['WS_PORT']);
log.info(`WS_PORT=${port}`); log.info(`WS_PORT=${wsPort}`);
} }
if (wsPort === port) {
log.error(`Websocket port (${wsPort}) should not be the same as HTTP port (${port})`);
process.exit(7);
}
if (typeof process.env['SEQUENCES'] === 'undefined') { if (typeof process.env['SEQUENCES'] === 'undefined') {
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env'); log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
process.exit(7); process.exit(7);
@ -161,29 +166,28 @@ function onWssConnection (ws : WebSocketExtended, req : Request) {
async function onClientMessage (data : any, ws : WebSocket) { async function onClientMessage (data : any, ws : WebSocket) {
let msg : Message = null; let msg : Message = null;
let res : Message = {};
try { try {
msg = JSON.parse(data); msg = JSON.parse(data);
} catch (err) { } catch (err) {
log.error('Error parsing message', err); log.error('Error parsing message', err);
} }
if (msg !== null && typeof msg.cmd !== 'undefined') { if (msg !== null && typeof msg.cmd !== 'undefined') {
res = await cmd(msg); await cmd(msg);
} }
ws.send(JSON.stringify(res));
} }
async function cmd (msg : Message) : Promise<Message> { async function cmd (msg : Message) {
let success : boolean = false
switch(msg.cmd) { switch(msg.cmd) {
case 'open' : case 'open' :
await cameraOpen(); await cameraOpen();
return { cmd : 'open' } break;
case 'close' : case 'close' :
await cameraClose(); await cameraClose();
return { cmd : 'close' } break;
case 'select' : case 'select' :
await select(msg.sequence) await select(msg.sequence);
return { cmd : 'select', sequence : msg.sequence } break;
default : default :
log.warn(`No matching command: ${msg.cmd}`); log.warn(`No matching command: ${msg.cmd}`);
} }
@ -191,19 +195,30 @@ async function cmd (msg : Message) : Promise<Message> {
async function cameraOpen () { async function cameraOpen () {
await camera.open(); await camera.open();
send({ cmd : 'open' });
} }
async function cameraClose () { async function cameraClose () {
await camera.close(); await camera.close();
send({ cmd : 'close' });
} }
async function select (id : string) { async function select (id : string) : Promise<boolean> {
const sequencesArr : SequenceObject[] = await Files.enumerateSequences(sequences); const sequencesArr : SequenceObject[] = await Files.enumerateSequences(sequences);
const seq : SequenceObject = sequencesArr.find(el => el.hash === id); const seq : SequenceObject = sequencesArr.find(el => el.hash === id);
if (typeof seq == 'undefined' || seq == null) { if (typeof seq == 'undefined' || seq == null) {
log.error('Sequence not found, maybe deleted?', new Error(`Cannot find sequence ${id}`)); log.error('Sequence not found, maybe deleted?', new Error(`Cannot find sequence ${id}`));
return false;
} }
await sequence.load(seq); await sequence.load(seq);
return true;
}
async function send (msg : Message) {
const msgStr : string = JSON.stringify(msg);
wss.clients.forEach((client : WebSocket ) => {
client.send(msgStr);
});
} }
app.get('/', async (req : Request, res : Response, next : NextFunction) => { app.get('/', async (req : Request, res : Response, next : NextFunction) => {
@ -221,7 +236,7 @@ async function main () {
camera = new Camera(); camera = new Camera();
display = new Display(width, height); display = new Display(width, height);
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT'])); //fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
sequence = new Sequence(camera, fd, display, ffprobe);
app.listen(port, async () => { app.listen(port, async () => {
log.info(`filmout_manager HTTP server running on port ${port}`); log.info(`filmout_manager HTTP server running on port ${port}`);
@ -233,6 +248,7 @@ async function main () {
//ffmpeg.listFormats(); //ffmpeg.listFormats();
//log.info(await TestImage.Focus(640, 480)); //log.info(await TestImage.Focus(640, 480));
sequence = new Sequence(camera, fd, display, ffprobe, send);
} }

View File

@ -4,12 +4,13 @@ import type { Logger } from 'winston';
import type { SequenceObject, ImageObject } from '../files'; import type { SequenceObject, ImageObject } from '../files';
import type { FD } from '../fd'; import type { FD } from '../fd';
import type { Camera } from '../camera'; import type { Camera } from '../camera';
import type { Display } from '../display'; import type { Display, Dimensions } from '../display';
import type { FFPROBE } from '../ffprobe'; import type { FFPROBE, VideoInfo } from '../ffprobe';
export class Sequence { export class Sequence {
private log : Logger; private log : Logger;
private current : SequenceObject = null; private current : SequenceObject = null;
private info : VideoInfo = null;
private images : ImageObject[] = []; private images : ImageObject[] = [];
private camera : Camera; private camera : Camera;
private display : Display; private display : Display;
@ -18,13 +19,15 @@ export class Sequence {
private running : boolean; private running : boolean;
private progress : number; private progress : number;
private frames : number; private frames : number;
private send : Function;
constructor (camera : Camera, fd : FD, display: Display, ffprobe : FFPROBE) { constructor (camera : Camera, fd : FD, display: Display, ffprobe : FFPROBE, send : Function) {
this.log = createLog('seq'); this.log = createLog('seq');
this.camera = camera; this.camera = camera;
this.fd = fd; this.fd = fd;
this.display = display; this.display = display;
this.ffprobe = ffprobe; this.ffprobe = ffprobe;
this.send = send;
} }
public start () { public start () {
@ -42,9 +45,11 @@ export class Sequence {
public load (seq : SequenceObject) { public load (seq : SequenceObject) {
this.current = seq; this.current = seq;
this.enumerate(); this.enumerate();
this.send({ cmd : 'select', sequence : seq.hash });
} }
private async enumerate () { private async enumerate () {
let screen : Dimensions;
if (this.current === null) { if (this.current === null) {
this.log.error('Cannot enumerate sequence because it is not set'); this.log.error('Cannot enumerate sequence because it is not set');
return; return;
@ -60,12 +65,20 @@ export class Sequence {
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`); this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
if (this.images.length > 0) { if (this.images.length > 0) {
console.dir(await this.ffprobe.info(this.images[0].path)); this.info = await this.ffprobe.info(this.images[0].path);
}
if (this.info !== null) {
screen = this.display.getScreen();
this.log.info(`Screen: ${screen.width},${screen.height}`);
this.log.info(`Sequence : ${this.info.width},${this.info.height}`);
this.display.setSource(this.info.width, this.info.height);
this.log.info(`Display : ${JSON.stringify(this.display.getDimensions())}`)
} }
} }
public unload () { public unload () {
this.current = null; this.current = null;
this.info = null;
this.images = []; this.images = [];
} }

View File

@ -14,3 +14,17 @@ html, body{
bottom: 10px; bottom: 10px;
width: 97vw; width: 97vw;
} }
#overlay{
position: fixed;
background: rgba(0, 0, 0, 0.5);
left: 0;
right: 0;
top: 0;
bottom: 0;
display: block;
}
#overlay.active{
display: none;
}

View File

@ -5,6 +5,7 @@ declare class Client {
constructor(); constructor();
private onMessage; private onMessage;
private onOpen; private onOpen;
private onClose;
private setSequence; private setSequence;
private cmd; private cmd;
disableClass(className: string): void; disableClass(className: string): void;
@ -17,5 +18,7 @@ declare class Client {
private receiveSelect; private receiveSelect;
fullscreen(): void; fullscreen(): void;
exitFullscreen(): void; exitFullscreen(): void;
private active;
private inactive;
} }
declare const client: Client; declare const client: Client;

View File

@ -5,6 +5,7 @@ class Client {
this.progress = document.getElementById('progress'); this.progress = document.getElementById('progress');
this.client = new WebSocket(uri); this.client = new WebSocket(uri);
this.client.onopen = this.onOpen.bind(this); this.client.onopen = this.onOpen.bind(this);
this.client.onclose = this.onClose.bind(this);
this.client.onmessage = this.onMessage.bind(this); this.client.onmessage = this.onMessage.bind(this);
} }
onMessage(event) { onMessage(event) {
@ -19,6 +20,12 @@ class Client {
onOpen(event) { onOpen(event) {
console.log('Connected'); console.log('Connected');
this.connected = true; this.connected = true;
this.active();
}
onClose(event) {
console.log('Disconnected');
this.connected = false;
this.inactive();
} }
setSequence(sequence) { setSequence(sequence) {
const percent = sequence.progress * 100.0; const percent = sequence.progress * 100.0;
@ -83,6 +90,7 @@ class Client {
receiveSelect(msg) { receiveSelect(msg) {
console.log('got select'); console.log('got select');
console.dir(msg); console.dir(msg);
document.getElementById('sequence').value = msg.sequence;
} }
fullscreen() { fullscreen() {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {
@ -97,6 +105,12 @@ class Client {
document.exitFullscreen(); document.exitFullscreen();
} }
} }
active() {
document.getElementById('overlay').classList.add('active');
}
inactive() {
document.getElementById('overlay').classList.remove('active');
}
} }
const client = new Client(); const client = new Client();
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../browser/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../browser/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM;IAKV;QAHQ,cAAS,GAAa,KAAK,CAAC;QAIlC,IAAI,GAAG,GAAY,qBAAqB,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAwB,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAEO,SAAS,CAAE,KAAW;QAC5B,MAAM,GAAG,GAAa,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;QACxD,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;YAC9D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAEO,MAAM,CAAE,KAAW;QACzB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEO,OAAO,CAAE,KAAW;QAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAEO,WAAW,CAAC,QAAwB;QAC1C,MAAM,OAAO,GAAY,QAAQ,CAAC,QAAQ,GAAG,KAAK,CAAC;QACnD,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;IACtD,CAAC;IAEO,GAAG,CAAE,GAAa;QACxB,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;YAChB,KAAK,MAAM;gBACT,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzB,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,MAAM;YACR,KAAK,QAAQ;gBACX,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBACxB,MAAM;YACR;gBACE,OAAO,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;gBACxC,MAAM;QACV,CAAC;IACH,CAAC;IAEM,YAAY,CAAE,SAAkB;QACrC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAsB,EAAE,EAAE;YAC5E,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,WAAW,CAAE,SAAkB;QACpC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAsB,EAAE,EAAE;YAC5E,EAAE,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,cAAc;QACnB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAEO,iBAAiB;QACvB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IAEM,eAAe;QACpB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAG,OAAO,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;IAEO,kBAAkB;QACxB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IAEM,UAAU;QACf,MAAM,QAAQ,GAAa,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAwB,CAAC,KAAK,CAAC;QAC5F,IAAI,GAAa,CAAC;QAClB,IAAI,QAAQ,KAAK,2BAA2B,EAAE,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,GAAG,GAAG,EAAE,GAAG,EAAG,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAEO,aAAa,CAAE,GAAa;QAClC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAwB,CAAC,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC;IACnF,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YAChC,QAAQ,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAEM,cAAc;QACnB,IAAI,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YAC/B,QAAQ,CAAC,cAAc,EAAE,CAAA;QAC3B,CAAC;IACH,CAAC;IAEO,MAAM;QACZ,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7D,CAAC;IACO,QAAQ;QACd,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,MAAM,GAAY,IAAI,MAAM,EAAE,CAAC"}

View File

@ -63,6 +63,7 @@
</div> </div>
</div> </div>
</div> </div>
<div id="overlay"></div>
<script src="/static/js/index.js"></script> <script src="/static/js/index.js"></script>
</body> </body>
</html> </html>