Check all local mounted harddrives for image sequence directories
This commit is contained in:
parent
273252ceae
commit
5b03182b3d
|
@ -0,0 +1,3 @@
|
||||||
|
export declare function envString(variable: string, defaultString: string): string;
|
||||||
|
export declare function envFloat(variable: string, defaultFloat: number): number;
|
||||||
|
export declare function envInt(variable: string, defaultInt: number): number;
|
|
@ -0,0 +1,17 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.envInt = exports.envFloat = exports.envString = void 0;
|
||||||
|
function envString(variable, defaultString) {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? process.env[variable] : defaultString;
|
||||||
|
}
|
||||||
|
exports.envString = envString;
|
||||||
|
function envFloat(variable, defaultFloat) {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? parseFloat(process.env[variable]) : defaultFloat;
|
||||||
|
}
|
||||||
|
exports.envFloat = envFloat;
|
||||||
|
function envInt(variable, defaultInt) {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? parseInt(process.env[variable]) : defaultInt;
|
||||||
|
}
|
||||||
|
exports.envInt = envInt;
|
||||||
|
module.exports = { envString, envFloat, envInt };
|
||||||
|
//# sourceMappingURL=index.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/env/index.ts"],"names":[],"mappings":";;;AAAA,SAAgB,SAAS,CAAE,QAAiB,EAAE,aAAsB;IACnE,OAAO,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;AAC7F,CAAC;AAFD,8BAEC;AAED,SAAgB,QAAQ,CAAE,QAAiB,EAAE,YAAqB;IACjE,OAAO,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AACxG,CAAC;AAFD,4BAEC;AAED,SAAgB,MAAM,CAAE,QAAiB,EAAE,UAAmB;IAC7D,OAAO,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AACpG,CAAC;AAFD,wBAEC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC"}
|
|
@ -1,9 +1,11 @@
|
||||||
interface SequenceObject {
|
interface SequenceObject {
|
||||||
|
created: number;
|
||||||
path: string;
|
path: string;
|
||||||
hash: string;
|
hash: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
interface VideoObject {
|
interface VideoObject {
|
||||||
|
created: number;
|
||||||
path: string;
|
path: string;
|
||||||
hash: string;
|
hash: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -17,6 +19,7 @@ export declare class Files {
|
||||||
private static sequencesDir;
|
private static sequencesDir;
|
||||||
static init(sequencesDir: string): Promise<boolean>;
|
static init(sequencesDir: string): Promise<boolean>;
|
||||||
static exists(path: string): Promise<boolean>;
|
static exists(path: string): Promise<boolean>;
|
||||||
|
static enumerateSequenceDirs(): Promise<string[]>;
|
||||||
static enumerateSequences(): Promise<SequenceObject[]>;
|
static enumerateSequences(): Promise<SequenceObject[]>;
|
||||||
static isSequence(dirPath: string): Promise<boolean>;
|
static isSequence(dirPath: string): Promise<boolean>;
|
||||||
static enumerateVideos(path: string): Promise<VideoObject[]>;
|
static enumerateVideos(path: string): Promise<VideoObject[]>;
|
||||||
|
|
|
@ -4,6 +4,8 @@ exports.Files = void 0;
|
||||||
const promises_1 = 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 env_1 = require("../env");
|
||||||
|
const os_1 = require("os");
|
||||||
const videoExtensions = [
|
const videoExtensions = [
|
||||||
'.mp4',
|
'.mp4',
|
||||||
'.mkv',
|
'.mkv',
|
||||||
|
@ -31,20 +33,61 @@ class Files {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static async enumerateSequenceDirs() {
|
||||||
|
const sequencesDirs = [
|
||||||
|
await (0, promises_1.realpath)(this.sequencesDir)
|
||||||
|
];
|
||||||
|
let drivesDir = null;
|
||||||
|
let drives = [];
|
||||||
|
let drive;
|
||||||
|
let user;
|
||||||
|
let stats;
|
||||||
|
if ((0, os_1.platform)() === 'darwin') {
|
||||||
|
drivesDir = `/Volumes/`;
|
||||||
|
}
|
||||||
|
else if ((0, os_1.platform)() === 'linux') {
|
||||||
|
user = (0, env_1.envString)('USER', null);
|
||||||
|
if (user !== null) {
|
||||||
|
drivesDir = (0, path_1.join)('/media', user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (drivesDir !== null) {
|
||||||
|
try {
|
||||||
|
drives = await (0, promises_1.readdir)(drivesDir);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let drive of drives) {
|
||||||
|
if (drive.substring(0, 1) === '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
drive = await (0, promises_1.realpath)((0, path_1.join)(drivesDir, drive));
|
||||||
|
stats = await (0, promises_1.lstat)(drive);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
sequencesDirs.push(drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sequencesDirs;
|
||||||
|
}
|
||||||
static async enumerateSequences() {
|
static async enumerateSequences() {
|
||||||
const dirs = [];
|
const dirs = [];
|
||||||
let all;
|
let all;
|
||||||
let stats;
|
let stats;
|
||||||
let dirPath;
|
let dirPath;
|
||||||
const paths = [
|
const paths = await this.enumerateSequenceDirs();
|
||||||
await (0, promises_1.realpath)(this.sequencesDir)
|
|
||||||
];
|
|
||||||
for (let path of paths) {
|
for (let path of paths) {
|
||||||
try {
|
try {
|
||||||
all = await (0, promises_1.readdir)(path);
|
all = await (0, promises_1.readdir)(path);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
throw err;
|
//
|
||||||
}
|
}
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
if (elem.substring(0, 1) === '.') {
|
if (elem.substring(0, 1) === '.') {
|
||||||
|
@ -60,16 +103,21 @@ class Files {
|
||||||
if (!stats.isDirectory()) {
|
if (!stats.isDirectory()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!this.isSequence(dirPath)) {
|
if (!await this.isSequence(dirPath)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
console.log(`Adding ${dirPath}`);
|
||||||
dirs.push({
|
dirs.push({
|
||||||
|
created: +stats.birthtime,
|
||||||
path: dirPath,
|
path: dirPath,
|
||||||
hash: hash_1.Hashes.stringHash(dirPath),
|
hash: hash_1.Hashes.stringHash(dirPath),
|
||||||
name: (0, path_1.basename)(dirPath)
|
name: (0, path_1.basename)(dirPath)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dirs.sort((a, b) => {
|
||||||
|
return b.created - a.created;
|
||||||
|
});
|
||||||
return dirs;
|
return dirs;
|
||||||
}
|
}
|
||||||
static async isSequence(dirPath) {
|
static async isSequence(dirPath) {
|
||||||
|
@ -83,6 +131,7 @@ class Files {
|
||||||
catch (err) {
|
catch (err) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
console.dir(`${dirPath} ${all.length}`);
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
filePath = (0, path_1.join)(dirPath, elem);
|
filePath = (0, path_1.join)(dirPath, elem);
|
||||||
try {
|
try {
|
||||||
|
@ -91,7 +140,8 @@ class Files {
|
||||||
catch (err) {
|
catch (err) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
if (stats.isFile() && imageExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
if (stats.isFile() && elem.substring(0, 1) !== '.' && imageExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
||||||
|
console.log(`Has file ${filePath}`);
|
||||||
sequence = true;
|
sequence = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -116,6 +166,7 @@ class Files {
|
||||||
stats = await (0, promises_1.lstat)(filePath);
|
stats = await (0, promises_1.lstat)(filePath);
|
||||||
if (stats.isFile() && videoExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
if (stats.isFile() && videoExtensions.indexOf((0, path_1.extname)((0, path_1.basename)(elem).toLowerCase())) !== -1) {
|
||||||
videos.push({
|
videos.push({
|
||||||
|
created: +stats.birthtime,
|
||||||
path: filePath,
|
path: filePath,
|
||||||
hash: hash_1.Hashes.stringHash(filePath),
|
hash: hash_1.Hashes.stringHash(filePath),
|
||||||
name: (0, path_1.basename)(filePath)
|
name: (0, path_1.basename)(filePath)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -34,6 +34,7 @@ const uuid_1 = require("uuid");
|
||||||
const Handlebars = __importStar(require("handlebars"));
|
const Handlebars = __importStar(require("handlebars"));
|
||||||
const ws_1 = require("ws");
|
const ws_1 = require("ws");
|
||||||
const log_1 = require("./log");
|
const log_1 = require("./log");
|
||||||
|
const env_1 = require("./env");
|
||||||
const files_1 = require("./files");
|
const files_1 = require("./files");
|
||||||
const testimage_1 = require("./testimage");
|
const testimage_1 = require("./testimage");
|
||||||
const fd_1 = require("./fd");
|
const fd_1 = require("./fd");
|
||||||
|
@ -81,76 +82,76 @@ async function createTemplate(filePath) {
|
||||||
async function settings() {
|
async function settings() {
|
||||||
let sequencesExists = false;
|
let sequencesExists = false;
|
||||||
let videosExists = false;
|
let videosExists = false;
|
||||||
if (typeof process.env['FD'] === 'undefined') {
|
if ((0, env_1.envString)('FD', null) === null) {
|
||||||
log.error('Please include an FD value containing the path to your fd binary in .env');
|
log.error('Please include an FD value containing the path to your fd binary in .env');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info(`FD=${process.env['FD']}`);
|
log.info(`FD=${process.env['FD']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FFMPEG'] === 'undefined') {
|
if ((0, env_1.envString)('FFMPEG', null) === null) {
|
||||||
log.error('Please include an FFMPEG value containing the path to your ffmpeg binary in .env');
|
log.error('Please include an FFMPEG value containing the path to your ffmpeg binary in .env');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info(`FFMPEG=${process.env['FFMPEG']}`);
|
log.info(`FFMPEG=${process.env['FFMPEG']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['WIDTH'] === 'undefined') {
|
if ((0, env_1.envInt)('WIDTH', null) === null) {
|
||||||
log.error('Please include a WIDTH value containing the width of the screen you are using in .env');
|
log.error('Please include a WIDTH value containing the width of the screen you are using in .env');
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
width = parseInt(process.env['WIDTH']);
|
width = (0, env_1.envInt)('WIDTH', 0);
|
||||||
log.info(`WIDTH=${width}`);
|
log.info(`WIDTH=${width}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['HEIGHT'] === 'undefined') {
|
if ((0, env_1.envInt)('HEIGHT', null) === null) {
|
||||||
log.error('Please include a HEIGHT value containing the height of the screen you are using in .env');
|
log.error('Please include a HEIGHT value containing the height of the screen you are using in .env');
|
||||||
process.exit(3);
|
process.exit(3);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
height = parseInt(process.env['HEIGHT']);
|
height = (0, env_1.envInt)('HEIGHT', 0);
|
||||||
log.info(`HEIGHT=${height}`);
|
log.info(`HEIGHT=${height}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FD_HOST'] === 'undefined') {
|
if ((0, env_1.envString)('FD_HOST', null) === null) {
|
||||||
log.error('Please include a FD_HOST value with the host that the fd socket server is hosted on in .env');
|
log.error('Please include a FD_HOST value with the host that the fd socket server is hosted on in .env');
|
||||||
process.exit(4);
|
process.exit(4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info(`FD_HOST=${process.env['FD_HOST']}`);
|
log.info(`FD_HOST=${process.env['FD_HOST']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FD_PORT'] === 'undefined') {
|
if ((0, env_1.envInt)('FD_PORT', null) === null) {
|
||||||
log.error('Please include a FD_PORT value with the port that the fd socket server is hosted on in .env');
|
log.error('Please include a FD_PORT value with the port that the fd socket server is hosted on in .env');
|
||||||
process.exit(5);
|
process.exit(5);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.info(`FD_PORT=${process.env['FD_PORT']}`);
|
log.info(`FD_PORT=${process.env['FD_PORT']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['PORT'] === 'undefined') {
|
if ((0, env_1.envInt)('PORT', null) === null) {
|
||||||
log.error('Please include a PORT value with the port that the HTTP web process is hosted on in .env');
|
log.error('Please include a PORT value with the port that the HTTP web process is hosted on in .env');
|
||||||
process.exit(6);
|
process.exit(6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
port = parseInt(process.env['PORT']);
|
port = (0, env_1.envInt)('PORT', 8080);
|
||||||
log.info(`PORT=${port}`);
|
log.info(`PORT=${port}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['WS_PORT'] === 'undefined') {
|
if ((0, env_1.envInt)('WS_PORT', null) === null) {
|
||||||
log.error('Please include a WSPORT value with the port that the WebSocket web process is hosted on in .env');
|
log.error('Please include a WSPORT value with the port that the WebSocket web process is hosted on in .env');
|
||||||
process.exit(6);
|
process.exit(6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
wsPort = parseInt(process.env['WS_PORT']);
|
wsPort = (0, env_1.envInt)('WS_PORT', 8081);
|
||||||
log.info(`WS_PORT=${wsPort}`);
|
log.info(`WS_PORT=${wsPort}`);
|
||||||
}
|
}
|
||||||
if (wsPort === port) {
|
if (wsPort === port) {
|
||||||
log.error(`Websocket port (${wsPort}) should not be the same as HTTP port (${port})`);
|
log.error(`Websocket port (${wsPort}) should not be the same as HTTP port (${port})`);
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
}
|
}
|
||||||
if (typeof process.env['SEQUENCES'] === 'undefined') {
|
if ((0, env_1.envString)('SEQUENCES', null) === null) {
|
||||||
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
|
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sequences = process.env['SEQUENCES'];
|
sequences = (0, env_1.envString)('SEQUENCES', null);
|
||||||
sequencesExists = await files_1.Files.init(sequences);
|
sequencesExists = await files_1.Files.init(sequences);
|
||||||
if (!sequencesExists) {
|
if (!sequencesExists) {
|
||||||
log.error(`The SEQUENCES directory in .env, ${sequences}, does not exist`);
|
log.error(`The SEQUENCES directory in .env, ${sequences}, does not exist`);
|
||||||
|
@ -158,12 +159,12 @@ async function settings() {
|
||||||
}
|
}
|
||||||
log.info(`SEQUENCES=${sequences}`);
|
log.info(`SEQUENCES=${sequences}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['VIDEOS'] === 'undefined') {
|
if ((0, env_1.envString)('VIDEOS', null) === null) {
|
||||||
log.error('Please include a VIDEOS directory where the videos will be located in .env');
|
log.error('Please include a VIDEOS directory where the videos will be located in .env');
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
videos = process.env['VIDEOS'];
|
videos = (0, env_1.envString)('VIDEOS', null);
|
||||||
videosExists = await files_1.Files.exists(videos);
|
videosExists = await files_1.Files.exists(videos);
|
||||||
if (!sequencesExists) {
|
if (!sequencesExists) {
|
||||||
log.error(`The VIDEOS directory in .env, ${videos}, does not exist`);
|
log.error(`The VIDEOS directory in .env, ${videos}, does not exist`);
|
||||||
|
@ -171,8 +172,8 @@ async function settings() {
|
||||||
}
|
}
|
||||||
log.info(`VIDEOS=${videos}`);
|
log.info(`VIDEOS=${videos}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['MOCK'] !== 'undefined') {
|
if ((0, env_1.envString)('MOCK', null) !== null) {
|
||||||
if (process.env['MOCK'].trim().toLowerCase() === "true" || process.env['MOCK'].trim() === '1') {
|
if ((0, env_1.envString)('MOCK', '').trim().toLowerCase() === "true" || (0, env_1.envString)('MOCK', '').trim() === '1') {
|
||||||
mock = true;
|
mock = true;
|
||||||
log.info(`MOCK=true`);
|
log.info(`MOCK=true`);
|
||||||
}
|
}
|
||||||
|
@ -461,12 +462,12 @@ app.get('/:width/:height/image.jpg', async (req, res, next) => {
|
||||||
async function main() {
|
async function main() {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
ffmpeg = new ffmpeg_1.FFMPEG(process.env['FFMPEG']);
|
ffmpeg = new ffmpeg_1.FFMPEG((0, env_1.envString)('FFMPEG', 'ffmpeg'));
|
||||||
ffprobe = new ffprobe_1.FFPROBE();
|
ffprobe = new ffprobe_1.FFPROBE();
|
||||||
image = new image_1.Image();
|
image = new image_1.Image();
|
||||||
camera = new camera_1.Camera(mock);
|
camera = new camera_1.Camera(mock);
|
||||||
display = new display_1.Display(width, height);
|
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']), mock);
|
fd = new fd_1.FD((0, env_1.envString)('FD', 'fd'), width, height, (0, env_1.envString)('FD_HOST', 'localhost'), (0, env_1.envInt)('FD_PORT', 8082), mock);
|
||||||
app.listen(port, async () => {
|
app.listen(port, async () => {
|
||||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
||||||
|
export function envString (variable : string, defaultString : string) : string {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? process.env[variable] : defaultString;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function envFloat (variable : string, defaultFloat : number ) : number {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? parseFloat(process.env[variable]) : defaultFloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function envInt (variable : string, defaultInt : number ) : number {
|
||||||
|
return typeof process.env[variable] !== 'undefined' ? parseInt(process.env[variable]) : defaultInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { envString, envFloat, envInt };
|
|
@ -3,14 +3,17 @@ import type { Stats } from 'fs';
|
||||||
import { Hashes } from '../hash';
|
import { Hashes } from '../hash';
|
||||||
import { basename, extname, join } from 'path';
|
import { basename, extname, join } from 'path';
|
||||||
import { envString } from '../env';
|
import { envString } from '../env';
|
||||||
|
import { platform } from 'os';
|
||||||
|
|
||||||
interface SequenceObject {
|
interface SequenceObject {
|
||||||
|
created : number,
|
||||||
path : string,
|
path : string,
|
||||||
hash : string,
|
hash : string,
|
||||||
name : string
|
name : string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VideoObject {
|
interface VideoObject {
|
||||||
|
created : number,
|
||||||
path : string,
|
path : string,
|
||||||
hash : string,
|
hash : string,
|
||||||
name : string
|
name : string
|
||||||
|
@ -54,21 +57,62 @@ export class Files {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async enumerateSequenceDirs () : Promise<string[]> {
|
||||||
|
const sequencesDirs : string[] = [
|
||||||
|
await realpath(this.sequencesDir)
|
||||||
|
];
|
||||||
|
let drivesDir : string = null;
|
||||||
|
let drives : string[] = [];
|
||||||
|
let drive : string;
|
||||||
|
let user : string;
|
||||||
|
let stats : Stats;
|
||||||
|
if (platform() === 'darwin') {
|
||||||
|
drivesDir = `/Volumes/`;
|
||||||
|
} else if (platform() === 'linux') {
|
||||||
|
user = envString('USER', null);
|
||||||
|
if (user !== null) {
|
||||||
|
drivesDir = join('/media', user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (drivesDir !== null) {
|
||||||
|
try {
|
||||||
|
drives = await readdir(drivesDir);
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let drive of drives) {
|
||||||
|
if (drive.substring(0, 1) === '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
drive = await realpath(join(drivesDir, drive));
|
||||||
|
stats = await lstat(drive);
|
||||||
|
} catch (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
sequencesDirs.push(drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sequencesDirs;
|
||||||
|
}
|
||||||
|
|
||||||
public static async enumerateSequences () : Promise<SequenceObject[]> {
|
public static async enumerateSequences () : Promise<SequenceObject[]> {
|
||||||
const dirs : SequenceObject[] = [];
|
const dirs : SequenceObject[] = [];
|
||||||
let all : string[];
|
let all : string[];
|
||||||
let stats : Stats;
|
let stats : Stats;
|
||||||
let dirPath : string;
|
let dirPath : string;
|
||||||
|
|
||||||
const paths : string[] = [
|
const paths : string[] = await this.enumerateSequenceDirs();
|
||||||
await realpath(this.sequencesDir)
|
|
||||||
];
|
|
||||||
|
|
||||||
for (let path of paths) {
|
for (let path of paths) {
|
||||||
try {
|
try {
|
||||||
all = await readdir(path)
|
all = await readdir(path)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw err;
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
|
@ -84,10 +128,11 @@ export class Files {
|
||||||
if (!stats.isDirectory()) {
|
if (!stats.isDirectory()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!this.isSequence(dirPath)) {
|
if (!await this.isSequence(dirPath)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dirs.push({
|
dirs.push({
|
||||||
|
created : + stats.birthtime,
|
||||||
path : dirPath,
|
path : dirPath,
|
||||||
hash : Hashes.stringHash(dirPath),
|
hash : Hashes.stringHash(dirPath),
|
||||||
name : basename(dirPath)
|
name : basename(dirPath)
|
||||||
|
@ -95,6 +140,10 @@ export class Files {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirs.sort((a, b) => {
|
||||||
|
return b.created - a.created;
|
||||||
|
})
|
||||||
|
|
||||||
return dirs;
|
return dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,11 +152,13 @@ export class Files {
|
||||||
let all : string[];
|
let all : string[];
|
||||||
let stats : Stats;
|
let stats : Stats;
|
||||||
let filePath : string;
|
let filePath : string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
all = await readdir(dirPath);
|
all = await readdir(dirPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let elem of all) {
|
for (let elem of all) {
|
||||||
filePath = join(dirPath, elem);
|
filePath = join(dirPath, elem);
|
||||||
try {
|
try {
|
||||||
|
@ -115,7 +166,7 @@ export class Files {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
if (stats.isFile() && imageExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
if (stats.isFile() && elem.substring(0, 1) !== '.' && imageExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
||||||
sequence = true;
|
sequence = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -143,6 +194,7 @@ export class Files {
|
||||||
stats = await lstat(filePath);
|
stats = await lstat(filePath);
|
||||||
if (stats.isFile() && videoExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
if (stats.isFile() && videoExtensions.indexOf(extname(basename(elem).toLowerCase())) !== -1) {
|
||||||
videos.push({
|
videos.push({
|
||||||
|
created : + stats.birthtime,
|
||||||
path : filePath,
|
path : filePath,
|
||||||
hash : Hashes.stringHash(filePath),
|
hash : Hashes.stringHash(filePath),
|
||||||
name : basename(filePath)
|
name : basename(filePath)
|
||||||
|
|
43
src/index.ts
43
src/index.ts
|
@ -14,7 +14,8 @@ import * as Handlebars from 'handlebars';
|
||||||
import { Server } from 'ws';
|
import { Server } from 'ws';
|
||||||
import type { WebSocket } from 'ws';
|
import type { WebSocket } from 'ws';
|
||||||
|
|
||||||
import { createLog } from './log'
|
import { createLog } from './log';
|
||||||
|
import { envString, envInt } from './env';
|
||||||
import { sendMail } from './mail';
|
import { sendMail } from './mail';
|
||||||
import { Files } from './files';
|
import { Files } from './files';
|
||||||
import type { SequenceObject, VideoObject, ImageObject } from './files';
|
import type { SequenceObject, VideoObject, ImageObject } from './files';
|
||||||
|
@ -78,56 +79,56 @@ async function createTemplate (filePath : string) : Promise<HandlebarsTemplateDe
|
||||||
async function settings () {
|
async function settings () {
|
||||||
let sequencesExists : boolean = false;
|
let sequencesExists : boolean = false;
|
||||||
let videosExists : boolean = false;
|
let videosExists : boolean = false;
|
||||||
if (typeof process.env['FD'] === 'undefined') {
|
if (envString('FD', null) === null) {
|
||||||
log.error('Please include an FD value containing the path to your fd binary in .env');
|
log.error('Please include an FD value containing the path to your fd binary in .env');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
} else {
|
} else {
|
||||||
log.info(`FD=${process.env['FD']}`);
|
log.info(`FD=${process.env['FD']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FFMPEG'] === 'undefined') {
|
if (envString('FFMPEG', null) === null) {
|
||||||
log.error('Please include an FFMPEG value containing the path to your ffmpeg binary in .env');
|
log.error('Please include an FFMPEG value containing the path to your ffmpeg binary in .env');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
} else {
|
} else {
|
||||||
log.info(`FFMPEG=${process.env['FFMPEG']}`);
|
log.info(`FFMPEG=${process.env['FFMPEG']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['WIDTH'] === 'undefined') {
|
if (envInt('WIDTH', null) === null) {
|
||||||
log.error('Please include a WIDTH value containing the width of the screen you are using in .env');
|
log.error('Please include a WIDTH value containing the width of the screen you are using in .env');
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
} else {
|
} else {
|
||||||
width = parseInt(process.env['WIDTH']);
|
width = envInt('WIDTH', 0);
|
||||||
log.info(`WIDTH=${width}`);
|
log.info(`WIDTH=${width}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['HEIGHT'] === 'undefined') {
|
if (envInt('HEIGHT', null) === null) {
|
||||||
log.error('Please include a HEIGHT value containing the height of the screen you are using in .env');
|
log.error('Please include a HEIGHT value containing the height of the screen you are using in .env');
|
||||||
process.exit(3);
|
process.exit(3);
|
||||||
} else {
|
} else {
|
||||||
height = parseInt(process.env['HEIGHT'])
|
height = envInt('HEIGHT', 0);
|
||||||
log.info(`HEIGHT=${height}`);
|
log.info(`HEIGHT=${height}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FD_HOST'] === 'undefined') {
|
if (envString('FD_HOST', null) === null) {
|
||||||
log.error('Please include a FD_HOST value with the host that the fd socket server is hosted on in .env');
|
log.error('Please include a FD_HOST value with the host that the fd socket server is hosted on in .env');
|
||||||
process.exit(4);
|
process.exit(4);
|
||||||
} else {
|
} else {
|
||||||
log.info(`FD_HOST=${process.env['FD_HOST']}`);
|
log.info(`FD_HOST=${process.env['FD_HOST']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['FD_PORT'] === 'undefined') {
|
if (envInt('FD_PORT', null) === null) {
|
||||||
log.error('Please include a FD_PORT value with the port that the fd socket server is hosted on in .env')
|
log.error('Please include a FD_PORT value with the port that the fd socket server is hosted on in .env')
|
||||||
process.exit(5);
|
process.exit(5);
|
||||||
} else {
|
} else {
|
||||||
log.info(`FD_PORT=${process.env['FD_PORT']}`);
|
log.info(`FD_PORT=${process.env['FD_PORT']}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['PORT'] === 'undefined') {
|
if (envInt('PORT', null) === null) {
|
||||||
log.error('Please include a PORT value with the port that the HTTP web process is hosted on in .env');
|
log.error('Please include a PORT value with the port that the HTTP web process is hosted on in .env');
|
||||||
process.exit(6);
|
process.exit(6);
|
||||||
} else {
|
} else {
|
||||||
port = parseInt(process.env['PORT']);
|
port = envInt('PORT', 8080);
|
||||||
log.info(`PORT=${port}`);
|
log.info(`PORT=${port}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['WS_PORT'] === 'undefined') {
|
if (envInt('WS_PORT', null) === null) {
|
||||||
log.error('Please include a WSPORT value with the port that the WebSocket web process is hosted on in .env');
|
log.error('Please include a WSPORT value with the port that the WebSocket web process is hosted on in .env');
|
||||||
process.exit(6);
|
process.exit(6);
|
||||||
} else {
|
} else {
|
||||||
wsPort = parseInt(process.env['WS_PORT']);
|
wsPort = envInt('WS_PORT', 8081);
|
||||||
log.info(`WS_PORT=${wsPort}`);
|
log.info(`WS_PORT=${wsPort}`);
|
||||||
}
|
}
|
||||||
if (wsPort === port) {
|
if (wsPort === port) {
|
||||||
|
@ -135,11 +136,11 @@ async function settings () {
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof process.env['SEQUENCES'] === 'undefined') {
|
if (envString('SEQUENCES', null) === null) {
|
||||||
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
|
log.error('Please include a SEQUENCES directory where the image sequences will be located in .env');
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
} else {
|
} else {
|
||||||
sequences = process.env['SEQUENCES'];
|
sequences = envString('SEQUENCES', null);
|
||||||
sequencesExists = await Files.init(sequences);
|
sequencesExists = await Files.init(sequences);
|
||||||
if (!sequencesExists) {
|
if (!sequencesExists) {
|
||||||
log.error(`The SEQUENCES directory in .env, ${sequences}, does not exist`);
|
log.error(`The SEQUENCES directory in .env, ${sequences}, does not exist`);
|
||||||
|
@ -147,11 +148,11 @@ async function settings () {
|
||||||
}
|
}
|
||||||
log.info(`SEQUENCES=${sequences}`);
|
log.info(`SEQUENCES=${sequences}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['VIDEOS'] === 'undefined') {
|
if (envString('VIDEOS', null) === null) {
|
||||||
log.error('Please include a VIDEOS directory where the videos will be located in .env');
|
log.error('Please include a VIDEOS directory where the videos will be located in .env');
|
||||||
process.exit(7);
|
process.exit(7);
|
||||||
} else {
|
} else {
|
||||||
videos = process.env['VIDEOS'];
|
videos = envString('VIDEOS', null);
|
||||||
videosExists = await Files.exists(videos);
|
videosExists = await Files.exists(videos);
|
||||||
if (!sequencesExists) {
|
if (!sequencesExists) {
|
||||||
log.error(`The VIDEOS directory in .env, ${videos}, does not exist`);
|
log.error(`The VIDEOS directory in .env, ${videos}, does not exist`);
|
||||||
|
@ -159,8 +160,8 @@ async function settings () {
|
||||||
}
|
}
|
||||||
log.info(`VIDEOS=${videos}`);
|
log.info(`VIDEOS=${videos}`);
|
||||||
}
|
}
|
||||||
if (typeof process.env['MOCK'] !== 'undefined') {
|
if (envString('MOCK', null) !== null) {
|
||||||
if (process.env['MOCK'].trim().toLowerCase() === "true" || process.env['MOCK'].trim() === '1') {
|
if (envString('MOCK', '').trim().toLowerCase() === "true" || envString('MOCK', '').trim() === '1') {
|
||||||
mock = true;
|
mock = true;
|
||||||
log.info(`MOCK=true`);
|
log.info(`MOCK=true`);
|
||||||
} else {
|
} else {
|
||||||
|
@ -461,12 +462,12 @@ app.get('/:width/:height/image.jpg', async (req : Request, res : Response, next
|
||||||
async function main () {
|
async function main () {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
ffmpeg = new FFMPEG(process.env['FFMPEG']);
|
ffmpeg = new FFMPEG(envString('FFMPEG', 'ffmpeg'));
|
||||||
ffprobe = new FFPROBE();
|
ffprobe = new FFPROBE();
|
||||||
image = new Image();
|
image = new Image();
|
||||||
camera = new Camera(mock);
|
camera = new Camera(mock);
|
||||||
display = new Display(width, height);
|
display = new Display(width, height);
|
||||||
fd = new FD(process.env['FD'], width, height, process.env['FD_HOST'], parseInt(process.env['FD_PORT']), mock);
|
fd = new FD(envString('FD', 'fd'), width, height, envString('FD_HOST', 'localhost'), envInt('FD_PORT', 8082), mock);
|
||||||
|
|
||||||
app.listen(port, async () => {
|
app.listen(port, async () => {
|
||||||
log.info(`filmout_manager HTTP server running on port ${port}`);
|
log.info(`filmout_manager HTTP server running on port ${port}`);
|
||||||
|
|
Loading…
Reference in New Issue