mirror of
https://github.com/ad1217/PrinterStatus
synced 2024-11-14 12:13:48 -05:00
server: Switch from generic http-proxy
to mjpeg-proxy
for webcam streams
This commit is contained in:
parent
5d19c77dce
commit
ecd5185dc4
101
server/package-lock.json
generated
101
server/package-lock.json
generated
@ -7,15 +7,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"http-proxy": "^1.18.1",
|
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
"mjpeg-proxy": "^0.3.0",
|
||||||
"node-fetch": "^2.6.5",
|
"node-fetch": "^2.6.5",
|
||||||
"ws": "^8.2.3"
|
"ws": "^8.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.8",
|
"@types/express": "^4.17.8",
|
||||||
"@types/express-ws": "^3.0.0",
|
"@types/express-ws": "^3.0.0",
|
||||||
"@types/http-proxy": "^1.17.4",
|
|
||||||
"@types/js-yaml": "^4.0.3",
|
"@types/js-yaml": "^4.0.3",
|
||||||
"@types/node": "^16.10.3",
|
"@types/node": "^16.10.3",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.5.12",
|
||||||
@ -122,15 +121,6 @@
|
|||||||
"@types/ws": "*"
|
"@types/ws": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/http-proxy": {
|
|
||||||
"version": "1.17.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
|
|
||||||
"integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/js-yaml": {
|
"node_modules/@types/js-yaml": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
||||||
@ -388,11 +378,6 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eventemitter3": {
|
|
||||||
"version": "4.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
|
||||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
|
|
||||||
},
|
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.17.1",
|
"version": "4.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||||
@ -484,25 +469,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
|
||||||
"version": "1.14.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
|
||||||
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"debug": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/form-data": {
|
"node_modules/form-data": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||||
@ -548,19 +514,6 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/http-proxy": {
|
|
||||||
"version": "1.18.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
|
||||||
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"eventemitter3": "^4.0.0",
|
|
||||||
"follow-redirects": "^1.0.0",
|
|
||||||
"requires-port": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
@ -653,6 +606,14 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mjpeg-proxy": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mjpeg-proxy/-/mjpeg-proxy-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-XpdOIPIw/as8djKkJyiT1YaxlM10vqA/KJmymnVl+bZcZYdLrNPYJjkJt+x+5I77vLxyD8QmDbmJrpb63YyRJw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -743,11 +704,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/requires-port": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
|
||||||
},
|
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
@ -1053,15 +1009,6 @@
|
|||||||
"@types/ws": "*"
|
"@types/ws": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/http-proxy": {
|
|
||||||
"version": "1.17.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz",
|
|
||||||
"integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/js-yaml": {
|
"@types/js-yaml": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz",
|
||||||
@ -1274,11 +1221,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||||
},
|
},
|
||||||
"eventemitter3": {
|
|
||||||
"version": "4.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
|
||||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
|
|
||||||
},
|
|
||||||
"express": {
|
"express": {
|
||||||
"version": "4.17.1",
|
"version": "4.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||||
@ -1346,11 +1288,6 @@
|
|||||||
"unpipe": "~1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"follow-redirects": {
|
|
||||||
"version": "1.14.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz",
|
|
||||||
"integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g=="
|
|
||||||
},
|
|
||||||
"form-data": {
|
"form-data": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||||
@ -1384,16 +1321,6 @@
|
|||||||
"toidentifier": "1.0.0"
|
"toidentifier": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"http-proxy": {
|
|
||||||
"version": "1.18.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
|
|
||||||
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
|
|
||||||
"requires": {
|
|
||||||
"eventemitter3": "^4.0.0",
|
|
||||||
"follow-redirects": "^1.0.0",
|
|
||||||
"requires-port": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
@ -1459,6 +1386,11 @@
|
|||||||
"mime-db": "1.50.0"
|
"mime-db": "1.50.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mjpeg-proxy": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mjpeg-proxy/-/mjpeg-proxy-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-XpdOIPIw/as8djKkJyiT1YaxlM10vqA/KJmymnVl+bZcZYdLrNPYJjkJt+x+5I77vLxyD8QmDbmJrpb63YyRJw=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -1525,11 +1457,6 @@
|
|||||||
"unpipe": "1.0.0"
|
"unpipe": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"requires-port": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
|
||||||
},
|
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.8",
|
"@types/express": "^4.17.8",
|
||||||
"@types/express-ws": "^3.0.0",
|
"@types/express-ws": "^3.0.0",
|
||||||
"@types/http-proxy": "^1.17.4",
|
|
||||||
"@types/js-yaml": "^4.0.3",
|
"@types/js-yaml": "^4.0.3",
|
||||||
"@types/node": "^16.10.3",
|
"@types/node": "^16.10.3",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.5.12",
|
||||||
@ -13,12 +12,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-ws": "^5.0.2",
|
"express-ws": "^5.0.2",
|
||||||
"http-proxy": "^1.18.1",
|
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
"mjpeg-proxy": "^0.3.0",
|
||||||
"node-fetch": "^2.6.5",
|
"node-fetch": "^2.6.5",
|
||||||
"ws": "^8.2.3"
|
"ws": "^8.2.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ts-node ./src/server.ts"
|
"start": "ts-node --files ./src/server.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
|
/// <reference path="mjpeg-proxy.d.ts"/>
|
||||||
|
import { MjpegProxy } from 'mjpeg-proxy';
|
||||||
|
|
||||||
import {ExtendedMessage} from '../../types/messages';
|
import {ExtendedMessage} from '../../types/messages';
|
||||||
import * as octoprint from '../../types/octoprint';
|
import * as octoprint from '../../types/octoprint';
|
||||||
@ -9,8 +11,8 @@ const PING_TIME = 10000;
|
|||||||
type Timeout = ReturnType<typeof setTimeout>;
|
type Timeout = ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
export default class OctoprintConnection {
|
export default class OctoprintConnection {
|
||||||
public webcamURL?: URL;
|
|
||||||
public name?: string;
|
public name?: string;
|
||||||
|
public webcamProxy?: MjpegProxy;
|
||||||
protected lastStatus?: ExtendedMessage;
|
protected lastStatus?: ExtendedMessage;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -34,7 +36,11 @@ export default class OctoprintConnection {
|
|||||||
|
|
||||||
async connect_websocket() {
|
async connect_websocket() {
|
||||||
const settings = await this.api_get('settings');
|
const settings = await this.api_get('settings');
|
||||||
this.webcamURL = new URL(settings.webcam.streamUrl, this.address);
|
const webcamURL = new URL(settings.webcam.streamUrl, this.address);
|
||||||
|
// TODO: handle recreating proxy on URL change
|
||||||
|
if (this.webcamProxy === undefined) {
|
||||||
|
this.webcamProxy = new MjpegProxy(webcamURL.toString());
|
||||||
|
}
|
||||||
this.name = settings.appearance.name;
|
this.name = settings.appearance.name;
|
||||||
|
|
||||||
// do passive login to get a session key from the API key
|
// do passive login to get a session key from the API key
|
||||||
|
12
server/src/mjpeg-proxy.d.ts
vendored
Normal file
12
server/src/mjpeg-proxy.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
declare module 'mjpeg-proxy' {
|
||||||
|
import {Request, Response} from 'express';
|
||||||
|
export class MjpegProxy {
|
||||||
|
mjpegOptions: URL;
|
||||||
|
|
||||||
|
constructor(mjpegUrl: string | URL);
|
||||||
|
proxyRequest(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): void;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
import * as express from 'express';
|
import * as express from 'express';
|
||||||
import * as httpProxy from 'http-proxy';
|
|
||||||
import * as yaml from 'js-yaml';
|
import * as yaml from 'js-yaml';
|
||||||
import * as expressWs from 'express-ws';
|
import * as expressWs from 'express-ws';
|
||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
@ -22,11 +21,6 @@ const config: configuration = yaml.load(
|
|||||||
fs.readFileSync('config.yaml', 'utf8')
|
fs.readFileSync('config.yaml', 'utf8')
|
||||||
) as configuration;
|
) as configuration;
|
||||||
|
|
||||||
const proxy = httpProxy.createProxyServer({});
|
|
||||||
proxy.on('error', function (e) {
|
|
||||||
console.error('Proxy failed:');
|
|
||||||
console.error(e);
|
|
||||||
});
|
|
||||||
let octoprintConnections: OctoPrintConnection[] = [];
|
let octoprintConnections: OctoPrintConnection[] = [];
|
||||||
|
|
||||||
function broadcast(data: WebSocket.Data) {
|
function broadcast(data: WebSocket.Data) {
|
||||||
@ -52,9 +46,8 @@ app.get('/webcam/:printer', (req, res) => {
|
|||||||
let printer: OctoPrintConnection | undefined = octoprintConnections.find(
|
let printer: OctoPrintConnection | undefined = octoprintConnections.find(
|
||||||
(op) => op.slug === req.params.printer
|
(op) => op.slug === req.params.printer
|
||||||
);
|
);
|
||||||
if (printer?.webcamURL) {
|
if (printer?.webcamProxy) {
|
||||||
req.url = ''; // truncate the url for passing to the proxy
|
return printer.webcamProxy.proxyRequest(req, res);
|
||||||
proxy.web(req, res, { target: printer.webcamURL.toString() });
|
|
||||||
} else res.status(404).send('Not Found: Printer not known or has no webcam.');
|
} else res.status(404).send('Not Found: Printer not known or has no webcam.');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -63,7 +56,12 @@ app.listen(PORT);
|
|||||||
function initPrinters() {
|
function initPrinters() {
|
||||||
octoprintConnections = Object.entries(config.printers).map(
|
octoprintConnections = Object.entries(config.printers).map(
|
||||||
([slug, printer]) =>
|
([slug, printer]) =>
|
||||||
new OctoPrintConnection(slug, printer.address, printer.apikey, broadcastPayload)
|
new OctoPrintConnection(
|
||||||
|
slug,
|
||||||
|
printer.address,
|
||||||
|
printer.apikey,
|
||||||
|
broadcastPayload
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user