restructure frames util so it can be used as a class on the back end

This commit is contained in:
Stewart Allen 2025-02-03 14:49:49 -05:00
commit d1815d8103
2 changed files with 77 additions and 52 deletions

View file

@ -3,17 +3,14 @@
* and stores the resulting jpeg stream into frame files * and stores the resulting jpeg stream into frame files
*/ */
const hexer = require('hexer'); const EventEmitter = require('events');
const util = require('util');
const args = process.argv.slice(2);
const tls = require('tls'); const tls = require('tls');
const fs = require('fs');
const [host, code, prefix] = args;
if (!(host && code)) { class FrameStream extends EventEmitter {
console.log('usage: frames [host] [code] (file-prefix)'); #remoteSocket;
return;
} constructor(host, code) {
super();
const abuf = new ArrayBuffer(80); const abuf = new ArrayBuffer(80);
const view = new DataView(abuf); const view = new DataView(abuf);
@ -26,38 +23,65 @@ view.setInt32(4, 0x3000, true);
new Uint8Array(abuf, 0x10, userBytes.length).set(userBytes); new Uint8Array(abuf, 0x10, userBytes.length).set(userBytes);
new Uint8Array(abuf, 0x30, codeBytes.length).set(codeBytes); new Uint8Array(abuf, 0x30, codeBytes.length).set(codeBytes);
const bufr = Buffer.from(abuf); let frame;
// console.log(hexer(bufr));
let pic; const remoteSocket = this.#remoteSocket = tls.connect({
let ind = 0;
const remoteSocket = tls.connect({
host, host,
port: 6000, port: 6000,
rejectUnauthorized: false rejectUnauthorized: false
}, () => { }, () => {
// send authentication to start jpeg frame stream // send authentication to start jpeg frame stream
remoteSocket.write(bufr); remoteSocket.write(Buffer.from(abuf));
this.emit('connect', host);
}); });
remoteSocket.on('data', (data) => { remoteSocket.on('data', (data) => {
// console.log('-- cam said --', data.length);
// console.log(hexer(data));
if (data.length === 16) { if (data.length === 16) {
// start of frame if (frame) {
if (pic) { this.emit('frame', frame);
// dump last completed frame frame = undefined;
fs.writeFileSync(`${prefix || "frame"}-${(++ind).toString().padStart(5,0)}.jpg`, pic);
console.log('received frame', ind);
pic = undefined;
} }
} else { } else {
pic = pic ? Buffer.concat([pic,data]) : data; frame = frame ? Buffer.concat([frame, data]) : data;
} }
}); });
remoteSocket.on('error', (err) => { remoteSocket.on('error', (error) => {
console.error('Remote connection error:', err.message);
clientSocket.destroy(); clientSocket.destroy();
this.emit('error', error);
}); });
remoteSocket.on('close', () => {
this.emit('close');
})
}
close() {
this.#remoteSocket.end();
}
}
if (require.main === module) {
const fs = require('fs');
const args = process.argv.slice(2);
const [host, code, prefix] = args;
if (!(host && code)) {
console.log('usage: frames [host] [code] (file-prefix)');
return;
}
console.log('frames extraction from', host);
let ind = 0;
new FrameStream(host, code)
.on('connect', host => {
console.log('connected to', host);
})
.on('frame', jpeg => {
fs.writeFileSync(`${prefix || "frame"}-${(++ind).toString().padStart(5, 0)}.jpg`, jpeg);
console.log('received frame', ind);
});
}
module.exports = { FrameStream };

View file

@ -1,5 +1,6 @@
const { Client } = require('@gridspace/basic-ftp'); const { Client } = require('@gridspace/basic-ftp');
const { Readable } = require('stream'); const { Readable } = require('stream');
const { FrameStream } = require('./frames');
module.exports = async (server) => { module.exports = async (server) => {