Fixed enumerateSequences and other methods for reading image and video files.
This commit is contained in:
parent
59afb15a10
commit
169940a83e
|
@ -33,10 +33,10 @@ class CameraSerialPortMock extends serialport_1.SerialPortMock {
|
||||||
this._mockSend(Commands.CAMERA_IDENTIFIER, 2);
|
this._mockSend(Commands.CAMERA_IDENTIFIER, 2);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA:
|
case Commands.CAMERA:
|
||||||
this._mockSend(Commands.CAMERA, 300);
|
this._mockSend(Commands.CAMERA, 250);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA_OPEN:
|
case Commands.CAMERA_OPEN:
|
||||||
this._mockSend(Commands.CAMERA_OPEN, 150);
|
this._mockSend(Commands.CAMERA_OPEN, 125);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA_CLOSE:
|
case Commands.CAMERA_CLOSE:
|
||||||
this._mockSend(Commands.CAMERA_FORWARD, 3);
|
this._mockSend(Commands.CAMERA_FORWARD, 3);
|
||||||
|
|
|
@ -8,9 +8,15 @@ interface VideoObject {
|
||||||
hash: string;
|
hash: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
interface ImageObject {
|
||||||
|
path: string;
|
||||||
|
hash: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
export declare class Files {
|
export declare class Files {
|
||||||
static exists(path: string): Promise<boolean>;
|
static exists(path: string): Promise<boolean>;
|
||||||
static enumerateSequences(path: string): Promise<SequenceObject[]>;
|
static enumerateSequences(path: string): Promise<SequenceObject[]>;
|
||||||
static enumerateVideos(path: string): Promise<VideoObject[]>;
|
static enumerateVideos(path: string): Promise<VideoObject[]>;
|
||||||
|
static enumerateSequence(path: string): Promise<ImageObject[]>;
|
||||||
}
|
}
|
||||||
export type { SequenceObject, VideoObject };
|
export type { SequenceObject, VideoObject, ImageObject };
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Files = void 0;
|
exports.Files = void 0;
|
||||||
const promises_1 = __importDefault(require("fs/promises"));
|
const promises_1 = require("fs/promises");
|
||||||
const hash_1 = require("../hash");
|
const hash_1 = require("../hash");
|
||||||
const path_1 = require("path");
|
const path_1 = require("path");
|
||||||
const fileExtensions = [
|
const videoExtensions = [
|
||||||
'.mp4',
|
'.mp4',
|
||||||
'.mkv',
|
'.mkv',
|
||||||
'.mov'
|
'.mov'
|
||||||
];
|
];
|
||||||
|
const imageExtensions = [
|
||||||
|
'.jpg',
|
||||||
|
'.jpeg',
|
||||||
|
'.png',
|
||||||
|
'.tif',
|
||||||
|
'.tiff',
|
||||||
|
'.bmp'
|
||||||
|
];
|
||||||
class Files {
|
class Files {
|
||||||
static async exists(path) {
|
static async exists(path) {
|
||||||
try {
|
try {
|
||||||
await promises_1.default.access(path);
|
await (0, promises_1.access)(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
@ -26,20 +31,23 @@ class Files {
|
||||||
const dirs = [];
|
const dirs = [];
|
||||||
let all;
|
let all;
|
||||||
let stats;
|
let stats;
|
||||||
|
let dirPath;
|
||||||
|
path = await (0, promises_1.realpath)(path);
|
||||||
try {
|
try {
|
||||||
all = await promises_1.default.readdir(path);
|
all = await (0, promises_1.readdir)(path);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
|
dirPath = (0, path_1.join)(path, elem);
|
||||||
try {
|
try {
|
||||||
stats = await promises_1.default.lstat(elem);
|
stats = await (0, promises_1.lstat)(dirPath);
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
dirs.push({
|
dirs.push({
|
||||||
path: elem,
|
path: dirPath,
|
||||||
hash: hash_1.Hashes.stringHash(elem),
|
hash: hash_1.Hashes.stringHash(dirPath),
|
||||||
name: (0, path_1.basename)(elem)
|
name: (0, path_1.basename)(dirPath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,20 +61,23 @@ class Files {
|
||||||
const videos = [];
|
const videos = [];
|
||||||
let all;
|
let all;
|
||||||
let stats;
|
let stats;
|
||||||
|
let filePath;
|
||||||
|
path = await (0, promises_1.realpath)(path);
|
||||||
try {
|
try {
|
||||||
all = await promises_1.default.readdir(path);
|
all = await (0, promises_1.readdir)(path);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
|
filePath = (0, path_1.join)(path, elem);
|
||||||
try {
|
try {
|
||||||
stats = await promises_1.default.lstat(elem);
|
stats = await (0, promises_1.lstat)(filePath);
|
||||||
if (stats.isFile() && fileExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem))) !== -1) {
|
if (stats.isFile() && videoExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
||||||
videos.push({
|
videos.push({
|
||||||
path: elem,
|
path: filePath,
|
||||||
hash: hash_1.Hashes.stringHash(elem),
|
hash: hash_1.Hashes.stringHash(filePath),
|
||||||
name: (0, path_1.basename)(elem)
|
name: (0, path_1.basename)(filePath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,6 +87,36 @@ class Files {
|
||||||
}
|
}
|
||||||
return videos;
|
return videos;
|
||||||
}
|
}
|
||||||
|
static async enumerateSequence(path) {
|
||||||
|
const dirs = [];
|
||||||
|
let all;
|
||||||
|
let stats;
|
||||||
|
let filePath;
|
||||||
|
path = await (0, promises_1.realpath)(path);
|
||||||
|
try {
|
||||||
|
all = await (0, promises_1.readdir)(path);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
for (let elem of all) {
|
||||||
|
filePath = (0, path_1.join)(path, elem);
|
||||||
|
try {
|
||||||
|
stats = await (0, promises_1.lstat)(filePath);
|
||||||
|
if (stats.isFile() && imageExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
||||||
|
dirs.push({
|
||||||
|
path: filePath,
|
||||||
|
hash: hash_1.Hashes.stringHash(filePath),
|
||||||
|
name: (0, path_1.basename)(filePath)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dirs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.Files = Files;
|
exports.Files = Files;
|
||||||
module.exports = { Files };
|
module.exports = { Files };
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAE7B,kCAAiC;AACjC,+BAAyC;AAczC,MAAM,cAAc,GAAc;IACjC,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,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,MAAM,EAAE,IAAI,cAAc,CAAC,OAAO,CAAC,IAAA,cAAO,EAAC,IAAA,eAAQ,EAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC9E,MAAM,CAAC,IAAI,CAAC;wBACX,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,MAAM,CAAC;IACf,CAAC;CACD;AAlED,sBAkEC;AAGD,MAAM,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":"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"}
|
|
@ -192,8 +192,8 @@ async function cameraOpen() {
|
||||||
}
|
}
|
||||||
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);
|
||||||
const videosArr = await files_1.Files.enumerateVideos(videos);
|
//const videosArr : VideoObject[] = await Files.enumerateVideos(videos);
|
||||||
const html = index({ sequences: sequencesArr, videos: videosArr, width, height });
|
const html = index({ sequences: sequencesArr, width, height });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,8 @@
|
||||||
|
import type { SequenceObject } from '../files';
|
||||||
export declare class Sequence {
|
export declare class Sequence {
|
||||||
|
private log;
|
||||||
private current;
|
private current;
|
||||||
|
private images;
|
||||||
private running;
|
private running;
|
||||||
private progress;
|
private progress;
|
||||||
private frames;
|
private frames;
|
||||||
|
@ -7,5 +10,8 @@ export declare class Sequence {
|
||||||
start(): void;
|
start(): void;
|
||||||
stop(): void;
|
stop(): void;
|
||||||
isRunning(): boolean;
|
isRunning(): boolean;
|
||||||
|
load(seq: SequenceObject): void;
|
||||||
|
private enumerate;
|
||||||
|
unload(): void;
|
||||||
getState(): SequenceState;
|
getState(): SequenceState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Sequence = void 0;
|
exports.Sequence = void 0;
|
||||||
|
const files_1 = require("../files");
|
||||||
|
const log_1 = require("../log");
|
||||||
class Sequence {
|
class Sequence {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.current = null;
|
this.current = null;
|
||||||
|
this.images = [];
|
||||||
|
this.log = (0, log_1.createLog)('seq');
|
||||||
}
|
}
|
||||||
start() {
|
start() {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
|
@ -14,6 +18,28 @@ class Sequence {
|
||||||
isRunning() {
|
isRunning() {
|
||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
|
load(seq) {
|
||||||
|
this.current = seq;
|
||||||
|
this.enumerate();
|
||||||
|
}
|
||||||
|
async enumerate() {
|
||||||
|
if (this.current === null) {
|
||||||
|
this.log.error('Cannot enumerate sequence because it is not set');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.images = await files_1.Files.enumerateSequence(this.current.path);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.log.error(`Error enumerating images in sequence: ${this.current.name}`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||||
|
}
|
||||||
|
unload() {
|
||||||
|
this.current = null;
|
||||||
|
this.images = [];
|
||||||
|
}
|
||||||
getState() {
|
getState() {
|
||||||
return {
|
return {
|
||||||
hash: this.current.hash,
|
hash: this.current.hash,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IAMpB;QALQ,YAAO,GAAoB,IAAI,CAAC;IAKxB,CAAC;IAEV,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,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;AA3BD,4BA2BC"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":";;;AAAA,oCAAiC;AACjC,gCAAkC;AAIlC,MAAa,QAAQ;IAQpB;QANQ,YAAO,GAAoB,IAAI,CAAC;QAChC,WAAM,GAAmB,EAAE,CAAC;QAMnC,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,CAAC,CAAC;IAC7B,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;IAC3H,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;AAzDD,4BAyDC"}
|
|
@ -47,10 +47,10 @@ class CameraSerialPortMock extends SerialPortMock {
|
||||||
this._mockSend(Commands.CAMERA_IDENTIFIER, 2);
|
this._mockSend(Commands.CAMERA_IDENTIFIER, 2);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA :
|
case Commands.CAMERA :
|
||||||
this._mockSend(Commands.CAMERA, 300);
|
this._mockSend(Commands.CAMERA, 250);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA_OPEN :
|
case Commands.CAMERA_OPEN :
|
||||||
this._mockSend(Commands.CAMERA_OPEN, 150);
|
this._mockSend(Commands.CAMERA_OPEN, 125);
|
||||||
break;
|
break;
|
||||||
case Commands.CAMERA_CLOSE :
|
case Commands.CAMERA_CLOSE :
|
||||||
this._mockSend(Commands.CAMERA_FORWARD, 3);
|
this._mockSend(Commands.CAMERA_FORWARD, 3);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'fs/promises';
|
import { access, lstat, readdir, realpath } from 'fs/promises';
|
||||||
import type { Stats } from 'fs';
|
import type { Stats } from 'fs';
|
||||||
import { Hashes } from '../hash';
|
import { Hashes } from '../hash';
|
||||||
import { basename, extname } from 'path';
|
import { basename, extname, join } from 'path';
|
||||||
|
|
||||||
interface SequenceObject {
|
interface SequenceObject {
|
||||||
path : string,
|
path : string,
|
||||||
|
@ -15,16 +15,31 @@ interface VideoObject {
|
||||||
name : string
|
name : string
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileExtensions : string[] = [
|
interface ImageObject {
|
||||||
|
path : string,
|
||||||
|
hash : string,
|
||||||
|
name : string
|
||||||
|
}
|
||||||
|
|
||||||
|
const videoExtensions : string[] = [
|
||||||
'.mp4',
|
'.mp4',
|
||||||
'.mkv',
|
'.mkv',
|
||||||
'.mov'
|
'.mov'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const imageExtensions : string[] = [
|
||||||
|
'.jpg',
|
||||||
|
'.jpeg',
|
||||||
|
'.png',
|
||||||
|
'.tif',
|
||||||
|
'.tiff',
|
||||||
|
'.bmp'
|
||||||
|
];
|
||||||
|
|
||||||
export class Files {
|
export class Files {
|
||||||
public static async exists (path : string) : Promise<boolean> {
|
public static async exists (path : string) : Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await fs.access(path);
|
await access(path);
|
||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
|
@ -35,20 +50,25 @@ export class Files {
|
||||||
const dirs : SequenceObject[] = [];
|
const dirs : SequenceObject[] = [];
|
||||||
let all : string[];
|
let all : string[];
|
||||||
let stats : Stats;
|
let stats : Stats;
|
||||||
|
let dirPath : string;
|
||||||
|
|
||||||
|
path = await realpath(path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
all = await fs.readdir(path)
|
all = await readdir(path)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
|
dirPath = join(path, elem);
|
||||||
try {
|
try {
|
||||||
stats = await fs.lstat(elem);
|
stats = await lstat(dirPath);
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
dirs.push({
|
dirs.push({
|
||||||
path : elem,
|
path : dirPath,
|
||||||
hash : Hashes.stringHash(elem),
|
hash : Hashes.stringHash(dirPath),
|
||||||
name : basename(elem)
|
name : basename(dirPath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -63,21 +83,25 @@ export class Files {
|
||||||
const videos : VideoObject[] = [];
|
const videos : VideoObject[] = [];
|
||||||
let all : string[];
|
let all : string[];
|
||||||
let stats : Stats;
|
let stats : Stats;
|
||||||
|
let filePath : string;
|
||||||
|
|
||||||
|
path = await realpath(path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
all = await fs.readdir(path)
|
all = await readdir(path)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
|
filePath = join(path, elem);
|
||||||
try {
|
try {
|
||||||
stats = await fs.lstat(elem);
|
stats = await lstat(filePath);
|
||||||
if (stats.isFile() && fileExtensions.indexOf(extname(basename(elem))) !== -1) {
|
if (stats.isFile() && videoExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
||||||
videos.push({
|
videos.push({
|
||||||
path : elem,
|
path : filePath,
|
||||||
hash : Hashes.stringHash(elem),
|
hash : Hashes.stringHash(filePath),
|
||||||
name : basename(elem)
|
name : basename(filePath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -87,7 +111,40 @@ export class Files {
|
||||||
|
|
||||||
return videos;
|
return videos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async enumerateSequence (path : string) : Promise<ImageObject[]> {
|
||||||
|
const dirs : ImageObject[] = [];
|
||||||
|
let all : string[];
|
||||||
|
let stats : Stats;
|
||||||
|
let filePath : string;
|
||||||
|
|
||||||
|
path = await realpath(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
all = await readdir(path)
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let elem of all) {
|
||||||
|
filePath = join(path, elem);
|
||||||
|
try {
|
||||||
|
stats = await lstat(filePath);
|
||||||
|
if (stats.isFile() && imageExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
||||||
|
dirs.push({
|
||||||
|
path : filePath,
|
||||||
|
hash : Hashes.stringHash(filePath),
|
||||||
|
name : basename(filePath)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { SequenceObject, VideoObject };
|
export type { SequenceObject, VideoObject, ImageObject };
|
||||||
module.exports = { Files };
|
module.exports = { Files };
|
||||||
|
|
|
@ -150,7 +150,6 @@ function onWssConnection (ws : WebSocketExtended, req : Request) {
|
||||||
ws.ip = ip;
|
ws.ip = ip;
|
||||||
ws.session = uuid();
|
ws.session = uuid();
|
||||||
ws.on('message', function (data) { onClientMessage(data, ws) });
|
ws.on('message', function (data) { onClientMessage(data, ws) });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onClientMessage (data : any, ws : WebSocket) {
|
async function onClientMessage (data : any, ws : WebSocket) {
|
||||||
|
@ -183,8 +182,8 @@ async function cameraOpen () {
|
||||||
|
|
||||||
app.get('/', async (req : Request, res : Response, next : NextFunction) => {
|
app.get('/', async (req : Request, res : Response, next : NextFunction) => {
|
||||||
const sequencesArr : SequenceObject[] = await Files.enumerateSequences(sequences);
|
const sequencesArr : SequenceObject[] = await Files.enumerateSequences(sequences);
|
||||||
const videosArr : VideoObject[] = await Files.enumerateVideos(videos);
|
//const videosArr : VideoObject[] = await Files.enumerateVideos(videos);
|
||||||
const html : string = index({ sequences : sequencesArr, videos : videosArr, width, height });
|
const html : string = index({ sequences : sequencesArr, width, height });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -204,8 +203,6 @@ 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();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
import type { SequenceObject } from '../files';
|
import { Files } from '../files';
|
||||||
|
import { createLog } from '../log'
|
||||||
|
import type { Logger } from 'winston';
|
||||||
|
import type { SequenceObject, ImageObject } from '../files';
|
||||||
|
|
||||||
export class Sequence {
|
export class Sequence {
|
||||||
|
private log : Logger;
|
||||||
private current : SequenceObject = null;
|
private current : SequenceObject = null;
|
||||||
|
private images : ImageObject[] = [];
|
||||||
private running : boolean;
|
private running : boolean;
|
||||||
private progress : number;
|
private progress : number;
|
||||||
private frames : number;
|
private frames : number;
|
||||||
|
|
||||||
constructor () {}
|
constructor () {
|
||||||
|
this.log = createLog('seq');
|
||||||
|
}
|
||||||
|
|
||||||
public start () {
|
public start () {
|
||||||
this.running = true;
|
this.running = true;
|
||||||
|
@ -20,6 +27,32 @@ export class Sequence {
|
||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public load (seq : SequenceObject) {
|
||||||
|
this.current = seq;
|
||||||
|
this.enumerate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async enumerate () {
|
||||||
|
if (this.current === null) {
|
||||||
|
this.log.error('Cannot enumerate sequence because it is not set');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.images = await Files.enumerateSequence(this.current.path);
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error(`Error enumerating images in sequence: ${this.current.name}`, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unload () {
|
||||||
|
this.current = null;
|
||||||
|
this.images = [];
|
||||||
|
}
|
||||||
|
|
||||||
public getState () : SequenceState {
|
public getState () : SequenceState {
|
||||||
return {
|
return {
|
||||||
hash : this.current.hash,
|
hash : this.current.hash,
|
||||||
|
|
|
@ -5,18 +5,20 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>Screen Resolution : {{width}}x{{height}}</div>
|
<div>Screen Resolution : {{width}}x{{height}}</div>
|
||||||
<select name="sequence" id="sequence">
|
<!--
|
||||||
<option> - Select Image Sequence - </option>
|
|
||||||
{{#each sequences}}
|
|
||||||
<option value="{{this.hash}}">{{this.name}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
<select name="video" id="video">
|
<select name="video" id="video">
|
||||||
<option> - Select Video - </option>
|
<option> - Select Video - </option>
|
||||||
{{#each videos}}
|
{{#each videos}}
|
||||||
<option value="{{this.hash}}">{{this.name}}</option>
|
<option value="{{this.hash}}">{{this.name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
|
-->
|
||||||
|
<select name="sequence" id="sequence">
|
||||||
|
<option> - Select Image Sequence - </option>
|
||||||
|
{{#each sequences}}
|
||||||
|
<option value="{{this.hash}}">{{this.name}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
<button id="open" onclick="client.cameraOpen()">Open Gate</button>
|
<button id="open" onclick="client.cameraOpen()">Open Gate</button>
|
||||||
<script src="/static/js/index.js"></script>
|
<script src="/static/js/index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue