UI updates and improved client connection logic to allow for multiple machines.
This commit is contained in:
parent
c33aaa2bec
commit
3c68496f5e
|
@ -139,7 +139,7 @@ class Client {
|
|||
private progressText : HTMLElement;
|
||||
|
||||
constructor () {
|
||||
let uri : string = 'ws://localhost:8082';
|
||||
let uri : string = this.getWebsocketUri();
|
||||
this.progress = document.getElementById('progress') as HTMLProgressElement;
|
||||
this.progressText = document.getElementById('progressText');
|
||||
this.client = new WebSocket(uri);
|
||||
|
@ -152,6 +152,14 @@ class Client {
|
|||
(document.getElementById('manualCtrlForm') as HTMLFormElement ).reset();
|
||||
this.disableClass('sequenceCtrl');
|
||||
this.disableClass('manualCtrl');
|
||||
this.setProgress({ hash: null, progress: 0 });
|
||||
}
|
||||
|
||||
private getWebsocketUri () : string {
|
||||
const host : string = (window.location.host + '').split(':')[0];
|
||||
//WEBSOCKET_PORT defined on page via template
|
||||
//@ts-ignore
|
||||
return `ws://${host}:${WEBSOCKET_PORT}`
|
||||
}
|
||||
|
||||
private onMessage (event : any) {
|
||||
|
@ -245,6 +253,9 @@ class Client {
|
|||
|
||||
private cmd (msg : Message) {
|
||||
switch (msg.cmd) {
|
||||
case 'ping' :
|
||||
this.receivePing();
|
||||
break;
|
||||
case 'open' :
|
||||
this.receiveCameraOpen();
|
||||
break;
|
||||
|
@ -283,6 +294,10 @@ class Client {
|
|||
this.client.send(JSON.stringify({ cmd : 'open' }));
|
||||
}
|
||||
|
||||
private receivePing() {
|
||||
this.sendPong();
|
||||
}
|
||||
|
||||
private receiveCameraOpen () {
|
||||
console.log('got camera open');
|
||||
this.enableClass('manualCtrl');
|
||||
|
@ -299,6 +314,10 @@ class Client {
|
|||
this.enableClass('manualCtrl');
|
||||
}
|
||||
|
||||
private sendPong () {
|
||||
this.client.send(JSON.stringify({ cmd : 'pong' }));
|
||||
}
|
||||
|
||||
public sendAdvance () {
|
||||
this.client.send(JSON.stringify({ cmd : 'advance' }));
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ export declare class Camera {
|
|||
private next;
|
||||
private port;
|
||||
private prefix;
|
||||
constructor();
|
||||
private mock;
|
||||
constructor(mock: boolean);
|
||||
private begin;
|
||||
private filter;
|
||||
private enumerate;
|
||||
|
|
|
@ -53,7 +53,7 @@ class CameraSerialPortMock extends serialport_1.SerialPortMock {
|
|||
}
|
||||
}
|
||||
class Camera {
|
||||
constructor() {
|
||||
constructor(mock) {
|
||||
this.ready = false;
|
||||
this.connected = false;
|
||||
this.serial = null;
|
||||
|
@ -61,6 +61,8 @@ class Camera {
|
|||
this.next = null;
|
||||
this.port = null;
|
||||
this.prefix = '';
|
||||
this.mock = false;
|
||||
this.mock = mock;
|
||||
this.log = (0, log_1.createLog)('camera');
|
||||
this.parser = new parser_readline_1.ReadlineParser({ delimiter: '\r\n' });
|
||||
this.begin();
|
||||
|
@ -74,7 +76,7 @@ class Camera {
|
|||
catch (err) {
|
||||
this.log.error(this.prefix + 'Error calling enumerate()', err);
|
||||
}
|
||||
if (ports.length > 0) {
|
||||
if (!this.mock && ports.length > 0) {
|
||||
for (let port of ports) {
|
||||
this.log.info(this.prefix + `Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
||||
selected = false;
|
||||
|
@ -87,7 +89,12 @@ class Camera {
|
|||
}
|
||||
}
|
||||
else {
|
||||
this.log.warn(this.prefix + `No USB serial devices found, connecting to MOCK...`);
|
||||
if (this.mock) {
|
||||
this.log.info(`Starting camera in MOCK mode due to system setting`);
|
||||
}
|
||||
else {
|
||||
this.log.warn(this.prefix + `No USB serial devices found, connecting to MOCK...`);
|
||||
}
|
||||
try {
|
||||
await this.connectMock();
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -42,6 +42,7 @@ const ffprobe_1 = require("./ffprobe");
|
|||
const camera_1 = require("./camera");
|
||||
const sequence_1 = require("./sequence");
|
||||
const image_1 = require("./image");
|
||||
let mock = false;
|
||||
const log = (0, log_1.createLog)('fm');
|
||||
const app = (0, express_1.default)();
|
||||
let wss;
|
||||
|
@ -167,6 +168,15 @@ async function settings() {
|
|||
}
|
||||
log.info(`VIDEOS=${videos}`);
|
||||
}
|
||||
if (typeof process.env['MOCK'] !== 'undefined') {
|
||||
if (process.env['MOCK'].trim().toLowerCase() === "true" || process.env['MOCK'].trim() === '1') {
|
||||
mock = true;
|
||||
log.info(`MOCK=true`);
|
||||
}
|
||||
else {
|
||||
mock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
function onWssConnection(ws, req) {
|
||||
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
||||
|
@ -193,6 +203,9 @@ async function onClientMessage(data, ws) {
|
|||
async function cmd(msg) {
|
||||
let success = false;
|
||||
switch (msg.cmd) {
|
||||
case 'pong':
|
||||
//received keepalive
|
||||
break;
|
||||
case 'open':
|
||||
await cameraOpen();
|
||||
break;
|
||||
|
@ -254,10 +267,13 @@ async function send(msg) {
|
|||
client.send(msgStr);
|
||||
});
|
||||
}
|
||||
async function keepAlive() {
|
||||
await send({ cmd: 'ping' });
|
||||
}
|
||||
app.get('/', async (req, res, next) => {
|
||||
const sequencesArr = await files_1.Files.enumerateSequences(sequences);
|
||||
//const videosArr : VideoObject[] = await Files.enumerateVideos(videos);
|
||||
const html = index({ sequences: sequencesArr, width, height });
|
||||
const html = index({ sequences: sequencesArr, width, height, wsPort });
|
||||
res.send(html);
|
||||
});
|
||||
app.get('/:width/:height/image.jpg', async (req, res, next) => {
|
||||
|
@ -294,9 +310,9 @@ async function main() {
|
|||
ffmpeg = new ffmpeg_1.FFMPEG(process.env['FFMPEG']);
|
||||
ffprobe = new ffprobe_1.FFPROBE();
|
||||
image = new image_1.Image();
|
||||
camera = new camera_1.Camera();
|
||||
camera = new camera_1.Camera(mock);
|
||||
display = new display_1.Display(width, height);
|
||||
fd = new fd_1.FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']), true);
|
||||
fd = new fd_1.FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']), mock);
|
||||
app.listen(port, async () => {
|
||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||
});
|
||||
|
@ -306,6 +322,7 @@ async function main() {
|
|||
//ffmpeg.listFormats();
|
||||
//log.info(await TestImage.Focus(640, 480));
|
||||
sequence = new sequence_1.Sequence(camera, fd, display, ffprobe, send);
|
||||
setInterval(keepAlive, 30000);
|
||||
}
|
||||
main();
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -78,8 +78,10 @@ export class Camera {
|
|||
private next : Function = null;
|
||||
private port : string = null;
|
||||
private prefix : string = '';
|
||||
private mock : boolean = false;
|
||||
|
||||
constructor () {
|
||||
constructor (mock : boolean) {
|
||||
this.mock = mock;
|
||||
this.log = createLog('camera');
|
||||
this.parser = new ReadlineParser({ delimiter: '\r\n' });
|
||||
this.begin();
|
||||
|
@ -93,7 +95,7 @@ export class Camera {
|
|||
} catch (err) {
|
||||
this.log.error(this.prefix + 'Error calling enumerate()', err);
|
||||
}
|
||||
if (ports.length > 0) {
|
||||
if (!this.mock && ports.length > 0) {
|
||||
for (let port of ports) {
|
||||
this.log.info(this.prefix + `Found USB serial device: ${port} ${selected ? '*' : ''}`);
|
||||
selected = false;
|
||||
|
@ -104,7 +106,11 @@ export class Camera {
|
|||
this.log.error(this.prefix + `Error connecting to ${ports[0]}`, err);
|
||||
}
|
||||
} else {
|
||||
this.log.warn(this.prefix + `No USB serial devices found, connecting to MOCK...`)
|
||||
if (this.mock) {
|
||||
this.log.info(`Starting camera in MOCK mode due to system setting`);
|
||||
} else {
|
||||
this.log.warn(this.prefix + `No USB serial devices found, connecting to MOCK...`)
|
||||
}
|
||||
try {
|
||||
await this.connectMock();
|
||||
} catch (err) {
|
||||
|
|
23
src/index.ts
23
src/index.ts
|
@ -29,6 +29,7 @@ import { Camera } from './camera';
|
|||
import { Sequence } from './sequence';
|
||||
import { Image } from './image';
|
||||
|
||||
let mock : boolean = false;
|
||||
const log : Logger = createLog('fm');
|
||||
const app : Express = express();
|
||||
let wss : Server;
|
||||
|
@ -155,6 +156,14 @@ async function settings () {
|
|||
}
|
||||
log.info(`VIDEOS=${videos}`);
|
||||
}
|
||||
if (typeof process.env['MOCK'] !== 'undefined') {
|
||||
if (process.env['MOCK'].trim().toLowerCase() === "true" || process.env['MOCK'].trim() === '1') {
|
||||
mock = true;
|
||||
log.info(`MOCK=true`);
|
||||
} else {
|
||||
mock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onWssConnection (ws : WebSocketExtended, req : Request) {
|
||||
|
@ -182,6 +191,9 @@ async function onClientMessage (data : any, ws : WebSocket) {
|
|||
async function cmd (msg : Message) {
|
||||
let success : boolean = false
|
||||
switch(msg.cmd) {
|
||||
case 'pong' :
|
||||
//received keepalive
|
||||
break;
|
||||
case 'open' :
|
||||
await cameraOpen();
|
||||
break;
|
||||
|
@ -252,10 +264,14 @@ async function send (msg : Message) {
|
|||
});
|
||||
}
|
||||
|
||||
async function keepAlive () {
|
||||
await send({ cmd : 'ping' });
|
||||
}
|
||||
|
||||
app.get('/', async (req : Request, res : Response, next : NextFunction) => {
|
||||
const sequencesArr : SequenceObject[] = await Files.enumerateSequences(sequences);
|
||||
//const videosArr : VideoObject[] = await Files.enumerateVideos(videos);
|
||||
const html : string = index({ sequences : sequencesArr, width, height });
|
||||
const html : string = index({ sequences : sequencesArr, width, height, wsPort });
|
||||
res.send(html);
|
||||
});
|
||||
|
||||
|
@ -291,9 +307,9 @@ async function main () {
|
|||
ffmpeg = new FFMPEG(process.env['FFMPEG']);
|
||||
ffprobe = new FFPROBE();
|
||||
image = new Image();
|
||||
camera = new Camera();
|
||||
camera = new Camera(mock);
|
||||
display = new Display(width, height);
|
||||
fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']), true);
|
||||
fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']), mock);
|
||||
|
||||
app.listen(port, async () => {
|
||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||
|
@ -306,6 +322,7 @@ async function main () {
|
|||
//ffmpeg.listFormats();
|
||||
//log.info(await TestImage.Focus(640, 480));
|
||||
sequence = new Sequence(camera, fd, display, ffprobe, send);
|
||||
setInterval(keepAlive, 30000);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,8 +33,10 @@ html, body{
|
|||
}
|
||||
|
||||
#frame{
|
||||
text-align: center;
|
||||
text-align: center !important;
|
||||
font-family: monospace;
|
||||
padding: 0;
|
||||
text-indent: 5px;
|
||||
}
|
||||
|
||||
#display{
|
||||
|
@ -61,13 +63,31 @@ fieldset.inline .field-row {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
fieldset.inline .field-row input {
|
||||
fieldset.inline .field-row input{
|
||||
max-width: 50px;
|
||||
}
|
||||
|
||||
fieldset.inline input.medium {
|
||||
max-width: 70px;
|
||||
}
|
||||
|
||||
progress {
|
||||
width: 97vw;
|
||||
position: absolute;
|
||||
bottom: 28px;
|
||||
left: 0.5vw;
|
||||
}
|
||||
|
||||
button.small{
|
||||
width: 35px;
|
||||
max-width: 35px;
|
||||
min-width: 35px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
button.medium{
|
||||
width: 50px;
|
||||
max-width: 50px;
|
||||
min-width: 50px;
|
||||
padding: 0 6px;
|
||||
}
|
|
@ -44,6 +44,7 @@ declare class Client {
|
|||
private progress;
|
||||
private progressText;
|
||||
constructor();
|
||||
private getWebsocketUri;
|
||||
private onMessage;
|
||||
private onOpen;
|
||||
private onClose;
|
||||
|
@ -57,9 +58,11 @@ declare class Client {
|
|||
disableClass(className: string): void;
|
||||
enableClass(className: string): void;
|
||||
sendCameraOpen(): void;
|
||||
private receivePing;
|
||||
private receiveCameraOpen;
|
||||
sendCameraClose(): void;
|
||||
private receiveCameraClose;
|
||||
private sendPong;
|
||||
sendAdvance(): void;
|
||||
sendRewind(): void;
|
||||
sendSelect(): void;
|
||||
|
|
|
@ -114,7 +114,7 @@ class Display {
|
|||
class Client {
|
||||
constructor() {
|
||||
this.connected = false;
|
||||
let uri = 'ws://localhost:8082';
|
||||
let uri = this.getWebsocketUri();
|
||||
this.progress = document.getElementById('progress');
|
||||
this.progressText = document.getElementById('progressText');
|
||||
this.client = new WebSocket(uri);
|
||||
|
@ -127,6 +127,11 @@ class Client {
|
|||
document.getElementById('manualCtrlForm').reset();
|
||||
this.disableClass('sequenceCtrl');
|
||||
this.disableClass('manualCtrl');
|
||||
this.setProgress({ hash: null, progress: 0 });
|
||||
}
|
||||
getWebsocketUri() {
|
||||
const host = (window.location.host + '').split(':')[0];
|
||||
return `ws://${host}:${WEBSOCKET_PORT}`;
|
||||
}
|
||||
onMessage(event) {
|
||||
const msg = JSON.parse(event.data);
|
||||
|
@ -206,6 +211,9 @@ class Client {
|
|||
}
|
||||
cmd(msg) {
|
||||
switch (msg.cmd) {
|
||||
case 'ping':
|
||||
this.receivePing();
|
||||
break;
|
||||
case 'open':
|
||||
this.receiveCameraOpen();
|
||||
break;
|
||||
|
@ -240,6 +248,9 @@ class Client {
|
|||
this.disableClass('manualCtrl');
|
||||
this.client.send(JSON.stringify({ cmd: 'open' }));
|
||||
}
|
||||
receivePing() {
|
||||
this.sendPong();
|
||||
}
|
||||
receiveCameraOpen() {
|
||||
console.log('got camera open');
|
||||
this.enableClass('manualCtrl');
|
||||
|
@ -253,6 +264,9 @@ class Client {
|
|||
console.log('got camera close');
|
||||
this.enableClass('manualCtrl');
|
||||
}
|
||||
sendPong() {
|
||||
this.client.send(JSON.stringify({ cmd: 'pong' }));
|
||||
}
|
||||
sendAdvance() {
|
||||
this.client.send(JSON.stringify({ cmd: 'advance' }));
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -80,23 +80,28 @@
|
|||
<fieldset id="displayAdjust" class="inline half">
|
||||
<legend>Display Adjust</legend>
|
||||
<form id="displayAdjustForm" onsubmit="return false;">
|
||||
<button id="offsetXPlus">X +</button>
|
||||
<button id="offsetXMinus">X -</button>
|
||||
<button id="offsetYPlus">Y +</button>
|
||||
<button id="offsetYMinus">Y -</button>
|
||||
<button class="small sequenceCtrl" id="offsetXPlus">X +</button>
|
||||
<button class="small sequenceCtrl" id="offsetXMinus">X -</button>
|
||||
<button class="small sequenceCtrl" id="offsetYPlus">Y +</button>
|
||||
<button class="small sequenceCtrl" id="offsetYMinus">Y -</button>
|
||||
<button class="small sequenceCtrl" id="widthPlus">W +</button>
|
||||
<button class="small sequenceCtrl" id="widthMinus">W -</button>
|
||||
<button class="small sequenceCtrl" id="heightPlus">H +</button>
|
||||
<button class="small sequenceCtrl" id="heightMinus">H -</button>
|
||||
</form>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div>
|
||||
<fieldset id="sequenceCtrl">
|
||||
<div class="flex">
|
||||
<fieldset class="inline half" id="sequenceCtrl">
|
||||
<legend>Sequence Controls</legend>
|
||||
<form id="sequenceCtrlForm" onsubmit="return false;">
|
||||
<button id="start" class="sequenceCtrl" onclick="client.sendStart();" disabled>Start</button>
|
||||
<button id="stop" class="sequenceCtrl" onclick="client.sendStop();" disabled>Stop</button>
|
||||
<button id="pause" class="sequenceCtrl" disabled>Pause</button>
|
||||
<button id="rewind" class="sequenceCtrl" onclick="client.sendRewind();" disabled><<</button>
|
||||
<input id="frame" value="00000" class="sequenceCtrl" disabled />
|
||||
<button id="advance" class="sequenceCtrl" onclick="client.sendAdvance()" disabled>>></button>
|
||||
<button id="start" class="medium sequenceCtrl" onclick="client.sendStart();" disabled>Start</button>
|
||||
<button id="stop" class="medium sequenceCtrl" onclick="client.sendStop();" disabled>Stop</button>
|
||||
<button id="rewind" class="small sequenceCtrl" onclick="client.sendToStart();" disabled><<</button>
|
||||
<button id="rewind" class="small sequenceCtrl" onclick="client.sendRewind();" disabled><</button>
|
||||
<input id="frame" type="number" value="00000" class="sequenceCtrl medium" disabled />
|
||||
<button id="advance" class="small sequenceCtrl" onclick="client.sendAdvance()" disabled>></button>
|
||||
<button id="advance" class="small sequenceCtrl" onclick="client.sendToEnd()" disabled>>></button>
|
||||
</form>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
@ -104,8 +109,8 @@
|
|||
<fieldset id="manualCtrl">
|
||||
<legend>Manual Controls</legend>
|
||||
<form id="manualCtrlForm" onsubmit="return false;" >
|
||||
<button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open Gate</button>
|
||||
<button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close Gate</button>
|
||||
<button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open</button>
|
||||
<button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close</button>
|
||||
<button id="focus" class="manualCtrl" onclick="">Focus</button>
|
||||
<button id="framing" class="manualCtrl" onclick="">Framing</button>
|
||||
</form>
|
||||
|
@ -123,6 +128,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="overlay"></div>
|
||||
<script>
|
||||
const WEBSOCKET_PORT = {{wsPort}};
|
||||
</script>
|
||||
<script src="/static/js/index.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue