Add the ffmpeg library. Add ability to list supported dmux formats

This commit is contained in:
mmcwilliams 2024-05-15 14:34:24 -04:00
parent 7632245332
commit b0c1431bd6
15 changed files with 342 additions and 40 deletions

14
dist/fd/index.d.ts vendored
View File

@ -12,14 +12,17 @@ declare enum Mode {
RGB_CHANNELS = 4,
INVERT_CHANNELS = 5
}
export interface fdOutgoingPosition {
x: number;
y: number;
w: number;
h: number;
}
export interface fdOutgoingMessage {
action: Action;
image: string;
mode?: Mode;
x?: number;
y?: number;
w?: number;
h?: number;
position?: fdOutgoingPosition;
exposure?: number[];
}
export interface fdIncomingMessage {
@ -52,8 +55,9 @@ export declare class FD {
private send;
private receive;
load(image: string, x: number, y: number, w: number, h: number): Promise<fdResult>;
display(image: string, exposure: number[]): Promise<fdResult>;
display(image: string, exposure?: number[]): Promise<fdResult>;
stop(image: string): Promise<fdResult>;
isConnected(): boolean;
private test;
}
export {};

42
dist/fd/index.js vendored
View File

@ -38,6 +38,7 @@ class FD {
this.shell = new shell_1.Shell([this.bin, `${this.width}`, `${this.height}`, `${this.port}`], this.logstd.bind(this), this.logsterr.bind(this), null, true);
this.startDisplay();
this.startClient();
this.test();
}
async startDisplay() {
this.log.info(`Launching fd binary ${this.bin}`);
@ -59,17 +60,30 @@ class FD {
}.bind(this));
this.client.on('close', () => {
this.log.info('Closing connection');
this.socketConnected = false;
});
this.client.on('error', (err) => {
this.log.error('Error:', err);
this.log.error('Error in socket client', err);
this.socketConnected = false;
this.shell.kill();
});
}
logstd(data) {
let parsed = null;
try {
parsed = JSON.parse(data);
}
catch (err) {
this.log.error(`Error parsing line ${data}`, err);
}
if (parsed !== null) {
this.log.info(`[shell] ${data}`);
if (data.indexOf('TCP server listening on port') !== -1 && data.indexOf(`${this.port}`) !== -1) {
if (typeof parsed['listening'] !== 'undefined' && parsed['listening'] === true
&& typeof parsed['port'] !== 'undefined' && parsed['port'] === this.port) {
this.socketAvailable = true;
}
}
}
logsterr(data) {
this.log.error(`[shell] ${data}`);
}
@ -90,10 +104,12 @@ class FD {
const msg = {
action: Action.LOAD,
image,
position: {
x,
y,
w,
h
}
};
const startTime = +new Date();
const promise = new Promise(function (resolve, reject) {
@ -112,9 +128,9 @@ class FD {
};
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
async display(image, exposure) {
async display(image, exposure = []) {
const msg = {
action: Action.DISPLAY,
image,
@ -137,7 +153,7 @@ class FD {
};
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
async stop(image) {
const msg = {
@ -161,11 +177,25 @@ class FD {
};
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
isConnected() {
return this.socketConnected;
}
async test() {
const img = '/Users/matthewmcwilliams9/src/filmout_display/img/4kSnake.png';
await (0, delay_1.delay)(2000);
await this.load(img, 100, 200, 640, 640);
await (0, delay_1.delay)(2000);
await this.display(img, [4000]);
await (0, delay_1.delay)(8000);
await this.load(img, 100, 200, 640, 640);
await (0, delay_1.delay)(1000);
await this.display(img);
await (0, delay_1.delay)(2000);
await this.stop(img);
process.exit();
}
}
exports.FD = FD;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

11
dist/ffmpeg/index.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
export declare class FFMPEG {
private bin;
private log;
private shell;
private formats;
private formatsInfo;
constructor(bin?: string);
private rawList;
private demuxerInfo;
listFormats(): Promise<string[]>;
}

81
dist/ffmpeg/index.js vendored Normal file
View File

@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FFMPEG = void 0;
const log_1 = require("../log");
const shell_1 = require("../shell");
const os_1 = require("os");
class FFMPEG {
constructor(bin = 'ffmpeg') {
this.formats = [];
this.formatsInfo = {};
this.bin = bin;
this.log = (0, log_1.createLog)('ffmpeg');
}
async rawList() {
const cmd = [this.bin, '-formats'];
return new Promise(async (resolve, reject) => {
this.shell = new shell_1.Shell(cmd, null, null, resolve, true);
await this.shell.execute();
});
}
async demuxerInfo(demuxer) {
const cmd = [this.bin, `ffmpeg -h demuxer=${demuxer}`];
return new Promise(async (resolve, reject) => {
this.shell = new shell_1.Shell(cmd, null, null, resolve, true);
await this.shell.execute();
});
}
async listFormats() {
let list = null;
let rows;
let key;
let description;
let info;
this.formats = [];
this.formatsInfo = {};
try {
list = await this.rawList();
}
catch (err) {
this.log.error('Error listing formats', err);
}
if (list !== null) {
rows = list.split(os_1.EOL);
for (let row of rows) {
//this.log.info(`"${row}"`);
if (row.startsWith(' DE ')) {
key = row.substring(4, row.length - 1).split(' ')[0];
description = row.replace(key, '').trim();
this.log.info(key);
/*try {
this.log.info(await this.demuxerInfo(key));
} catch (err) {
this.log.error(err);
}*/
this.formats.push(key);
this.formatsInfo[key] = {
description
};
}
else if (row.startsWith(' D ')) {
key = row.substring(4, row.length - 1).split(' ')[0];
description = row.replace(key, '').trim();
this.log.info(key);
/*try {
this.log.info(await this.demuxerInfo(key));
} catch (err) {
this.log.error(err);
}*/
this.formats.push(key);
this.formatsInfo[key] = {
description
};
}
}
}
return this.formats;
}
}
exports.FFMPEG = FFMPEG;
module.exports = { FFMPEG };
//# sourceMappingURL=index.js.map

1
dist/ffmpeg/index.js.map vendored Normal file
View File

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

View File

@ -3,8 +3,14 @@ interface SequenceObject {
hash: string;
name: string;
}
interface VideoObject {
path: string;
hash: string;
name: string;
}
export declare class Files {
static exists(path: string): Promise<boolean>;
static enumerateSequences(path: string): Promise<SequenceObject[]>;
static enumerateVideos(path: string): Promise<VideoObject[]>;
}
export type { SequenceObject };
export type { SequenceObject, VideoObject };

11
dist/files/index.js vendored
View File

@ -7,6 +7,11 @@ exports.Files = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const hash_1 = require("../hash");
const path_1 = require("path");
const fileExtension = [
'.mp4',
'.mkv',
'.mov'
];
class Files {
static async exists(path) {
try {
@ -44,6 +49,12 @@ class Files {
}
return dirs;
}
static async enumerateVideos(path) {
const videos = [];
let all;
let stats;
return videos;
}
}
exports.Files = Files;
module.exports = { Files };

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAE7B,kCAAiC;AACjC,+BAAgC;AAQhC,MAAa,KAAK;IACV,MAAM,CAAC,KAAK,CAAC,MAAM,CAAE,IAAa;QACxC,IAAI,CAAC;YACJ,MAAM,kBAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAE,IAAa;QACpD,MAAM,IAAI,GAAsB,EAAE,CAAC;QACnC,IAAI,GAAc,CAAC;QACnB,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC;YACJ,GAAG,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;QACX,CAAC;QAED,KAAK,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC;gBACJ,KAAK,GAAG,MAAM,kBAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC;wBACT,IAAI,EAAG,IAAI;wBACX,IAAI,EAAG,aAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC9B,IAAI,EAAG,IAAA,eAAQ,EAAC,IAAI,CAAC;qBACrB,CAAC,CAAC;gBACJ,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,EAAE;YACH,CAAC;QACF,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AArCD,sBAqCC;AAGD,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAE7B,kCAAiC;AACjC,+BAAyC;AAczC,MAAM,aAAa,GAAc;IAChC,MAAM;IACN,MAAM;IACN,MAAM;CACN,CAAC;AAEF,MAAa,KAAK;IACV,MAAM,CAAC,KAAK,CAAC,MAAM,CAAE,IAAa;QACxC,IAAI,CAAC;YACJ,MAAM,kBAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAE,IAAa;QACpD,MAAM,IAAI,GAAsB,EAAE,CAAC;QACnC,IAAI,GAAc,CAAC;QACnB,IAAI,KAAa,CAAC;QAClB,IAAI,CAAC;YACJ,GAAG,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;QACX,CAAC;QAED,KAAK,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC;gBACJ,KAAK,GAAG,MAAM,kBAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC;wBACT,IAAI,EAAG,IAAI;wBACX,IAAI,EAAG,aAAM,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC9B,IAAI,EAAG,IAAA,eAAQ,EAAC,IAAI,CAAC;qBACrB,CAAC,CAAC;gBACJ,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,EAAE;YACH,CAAC;QACF,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,eAAe,CAAE,IAAa;QACjD,MAAM,MAAM,GAAmB,EAAE,CAAC;QAClC,IAAI,GAAc,CAAC;QACnB,IAAI,KAAa,CAAC;QAElB,OAAO,MAAM,CAAC;IACf,CAAC;CACD;AA7CD,sBA6CC;AAGD,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}

4
dist/index.js vendored
View File

@ -33,9 +33,11 @@ const body_parser_1 = __importDefault(require("body-parser"));
const Handlebars = __importStar(require("handlebars"));
const log_1 = require("./log");
const files_1 = require("./files");
const ffmpeg_1 = require("./ffmpeg");
const log = (0, log_1.createLog)('fm');
const app = (0, express_1.default)();
let fd;
let ffmpeg;
let index;
let port;
let sequences;
@ -139,10 +141,12 @@ app.get('/', async (req, res, next) => {
async function main() {
await settings();
index = await createTemplate('./views/index.hbs');
ffmpeg = new ffmpeg_1.FFMPEG();
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
app.listen(port, async () => {
log.info(`filmout_manager HTTP server running on port ${port}`);
});
log.info(await ffmpeg.listFormats());
}
main();
//# sourceMappingURL=index.js.map

2
dist/index.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yBAAsB;AACtB,sDAA8B;AAE9B,2DAA6B;AAI7B,8DAAqC;AAKrC,uDAAyC;AAGzC,+BAAiC;AAEjC,mCAAgC;AAMhC,MAAM,GAAG,GAAY,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;AACrC,MAAM,GAAG,GAAa,IAAA,iBAAO,GAAE,CAAC;AAChC,IAAI,EAAO,CAAC;AACZ,IAAI,KAAuC,CAAC;AAE5C,IAAI,IAAa,CAAC;AAClB,IAAI,SAAkB,CAAC;AACvB,IAAI,MAAe,CAAC;AACpB,IAAI,KAAc,CAAC;AACnB,IAAI,MAAe,CAAC;AAEpB,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;AAExC,GAAG,CAAC,GAAG,CAAC,qBAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3B,GAAG,CAAC,GAAG,CAAC,qBAAU,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEnD,KAAK,UAAU,cAAc,CAAE,QAAiB;IAC/C,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACf,OAAO,IAAI,CAAA;IACZ,CAAC;IACD,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,QAAQ;IACtB,IAAI,eAAe,GAAa,KAAK,CAAC;IACtC,IAAI,YAAY,GAAa,KAAK,CAAC;IACnC,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC;QAC9C,GAAG,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,WAAW,EAAE,CAAC;QACjD,GAAG,CAAC,KAAK,CAAC,uFAAuF,CAAC,CAAC;QACnG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,EAAE,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,yFAAyF,CAAC,CAAC;QACrG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QACxC,GAAG,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,WAAW,EAAE,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;QACzG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,WAAW,EAAE,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAA;QACxG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,WAAW,EAAE,CAAC;QAChD,GAAG,CAAC,KAAK,CAAC,0FAA0F,CAAC,CAAC;QACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,KAAK,CAAC,wFAAwF,CAAC,CAAC;QACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACrC,eAAe,GAAG,MAAM,aAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,eAAe,EAAE,CAAC;YACtB,GAAG,CAAC,KAAK,CAAC,oCAAoC,SAAS,kBAAkB,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,EAAE,CAAC;QAClD,GAAG,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;SAAM,CAAC;QACP,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,YAAY,GAAG,MAAM,aAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,eAAe,EAAE,CAAC;YACtB,GAAG,CAAC,KAAK,CAAC,iCAAiC,MAAM,kBAAkB,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;IAC9B,CAAC;AACF,CAAC;AAED,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAa,EAAE,GAAc,EAAE,IAAmB,EAAE,EAAE;IACzE,MAAM,IAAI,GAAsB,MAAM,aAAK,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAY,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IAClB,MAAM,QAAQ,EAAE,CAAC;IACjB,KAAK,GAAG,MAAM,cAAc,CAAC,mBAAmB,CAAC,CAAC;IAClD,6GAA6G;IAC7G,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;QAC3B,GAAG,CAAC,IAAI,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACJ,CAAC;AAGD,IAAI,EAAE,CAAC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}

View File

@ -21,14 +21,18 @@ enum Mode {
INVERT_CHANNELS
}
export interface fdOutgoingPosition {
x : number,
y : number,
w : number,
h : number
}
export interface fdOutgoingMessage {
action : Action,
image : string,
mode? : Mode,
x? : number,
y? : number,
w? : number,
h? : number,
position? : fdOutgoingPosition,
exposure? : number[]
}
@ -68,6 +72,7 @@ export class FD {
this.shell = new Shell([ this.bin, `${this.width}`, `${this.height}`, `${this.port}` ], this.logstd.bind(this), this.logsterr.bind(this), null, true);
this.startDisplay();
this.startClient();
this.test();
}
private async startDisplay () {
@ -93,19 +98,31 @@ export class FD {
this.client.on('close', () => {
this.log.info('Closing connection');
this.socketConnected = false;
});
this.client.on('error', (err : Error) => {
this.log.error('Error:', err);
this.log.error('Error in socket client', err);
this.socketConnected = false;
this.shell.kill();
});
}
private logstd (data : string ) {
let parsed : any = null;
try {
parsed = JSON.parse(data);
} catch (err) {
this.log.error(`Error parsing line ${data}`, err);
}
if (parsed !== null) {
this.log.info(`[shell] ${data}`);
if (data.indexOf('TCP server listening on port') !== -1 && data.indexOf(`${this.port}`) !== -1) {
if (typeof parsed['listening'] !== 'undefined' && parsed['listening'] === true
&& typeof parsed['port'] !== 'undefined' && parsed['port'] === this.port) {
this.socketAvailable = true;
}
}
}
private logsterr (data : string) {
this.log.error(`[shell] ${data}`);
@ -130,10 +147,12 @@ export class FD {
const msg : fdOutgoingMessage = {
action : Action.LOAD,
image,
position : {
x,
y,
w,
h
}
};
const startTime : number = +new Date();
const promise : Promise<fdResult> = new Promise(function (resolve : Function, reject : Function) {
@ -151,10 +170,10 @@ export class FD {
}
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
public async display (image : string, exposure : number[]) : Promise<fdResult> {
public async display (image : string, exposure : number[] = []) : Promise<fdResult> {
const msg : fdOutgoingMessage = {
action : Action.DISPLAY,
image,
@ -176,7 +195,7 @@ export class FD {
}
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
public async stop (image : string) : Promise<fdResult> {
@ -200,11 +219,32 @@ export class FD {
}
}.bind(this));
this.send(msg);
return promise;
return await promise;
}
public isConnected () : boolean {
return this.socketConnected;
}
private async test () {
const img = '/Users/matthewmcwilliams9/src/filmout_display/img/4kSnake.png';
await delay(2000);
await this.load(img, 100, 200, 640, 640);
await delay(2000);
await this.display(img, [ 4000 ] );
await delay(8000);
await this.load(img, 100, 200, 640, 640);
await delay(1000);
await this.display (img);
await delay(2000);
await this.stop(img);
process.exit();
}
}

90
src/ffmpeg/index.ts Normal file
View File

@ -0,0 +1,90 @@
import type { Logger } from 'winston';
import { createLog } from '../log'
import { Shell } from '../shell';
import { delay } from '../delay';
import { EOL } from 'os';
export class FFMPEG {
private bin : string;
private log : Logger;
private shell : Shell;
private formats : string[] = [];
private formatsInfo : any = {};
constructor (bin: string = 'ffmpeg') {
this.bin = bin;
this.log = createLog('ffmpeg');
}
private async rawList () : Promise<string> {
const cmd : string[] = [ this.bin, '-formats' ];
return new Promise(async (resolve : Function, reject : Function) => {
this.shell = new Shell(cmd, null, null, resolve, true);
await this.shell.execute();
});
}
private async demuxerInfo (demuxer : string) : Promise<string> {
const cmd : string[] = [ this.bin, `ffmpeg -h demuxer=${demuxer}` ];
return new Promise(async (resolve : Function, reject : Function) => {
this.shell = new Shell(cmd, null, null, resolve, true);
await this.shell.execute();
});
}
async listFormats () : Promise<string[]> {
let list : string = null;
let rows : string[];
let key : string;
let description : string;
let info : string;
this.formats = [];
this.formatsInfo = {};
try {
list = await this.rawList();
} catch (err) {
this.log.error('Error listing formats', err);
}
if (list !== null) {
rows = list.split(EOL);
for (let row of rows) {
//this.log.info(`"${row}"`);
if (row.startsWith(' DE ')) {
key = row.substring(4, row.length - 1).split(' ')[0];
description = row.replace(key, '').trim();
this.log.info(key);
/*try {
this.log.info(await this.demuxerInfo(key));
} catch (err) {
this.log.error(err);
}*/
this.formats.push(key);
this.formatsInfo[key] = {
description
};
} else if (row.startsWith(' D ')) {
key = row.substring(4, row.length - 1).split(' ')[0];
description = row.replace(key, '').trim();
this.log.info(key);
/*try {
this.log.info(await this.demuxerInfo(key));
} catch (err) {
this.log.error(err);
}*/
this.formats.push(key);
this.formatsInfo[key] = {
description
};
}
}
}
return this.formats;
}
}
module.exports = { FFMPEG };

View File

@ -1,7 +1,7 @@
import fs from 'fs/promises';
import type { Stats } from 'fs';
import { Hashes } from '../hash';
import { basename } from 'path';
import { basename, extname } from 'path';
interface SequenceObject {
path : string,
@ -9,6 +9,18 @@ interface SequenceObject {
name : string
}
interface VideoObject {
path : string,
hash : string,
name : string
}
const fileExtension : string[] = [
'.mp4',
'.mkv',
'.mov'
];
export class Files {
public static async exists (path : string) : Promise<boolean> {
try {
@ -46,7 +58,15 @@ export class Files {
return dirs;
}
public static async enumerateVideos (path : string) : Promise<VideoObject[]> {
const videos : VideoObject[] = [];
let all : string[];
let stats : Stats;
return videos;
}
}
export type { SequenceObject };
export type { SequenceObject, VideoObject };
module.exports = { Files };

View File

@ -16,14 +16,16 @@ import { Server } from 'ws';
import { createLog } from './log'
import { sendMail } from './mail';
import { Files } from './files';
import type { SequenceObject } from './files';
import type { SequenceObject, VideoObject } from './files';
import { Shell } from './shell';
import { delay } from './delay';
import { FD } from './fd';
import { FFMPEG } from './ffmpeg';
const log : Logger = createLog('fm');
const app : Express = express();
let fd : FD;
let ffmpeg : FFMPEG;
let index : HandlebarsTemplateDelegate<any>;
let port : number;
@ -125,10 +127,12 @@ app.get('/', async (req : Request, res : Response, next : NextFunction) => {
async function main () {
await settings();
index = await createTemplate('./views/index.hbs');
ffmpeg = new FFMPEG();
//fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']));
app.listen(port, async () => {
log.info(`filmout_manager HTTP server running on port ${port}`);
});
log.info(await ffmpeg.listFormats());
}