Filmout supports still images. Uses FFMPEG to convert to png, still. Should use sharp and re-sample the image to the maximum allowed for the screen in the smallest dimension.

This commit is contained in:
mmcwilliams 2019-07-07 00:02:01 -04:00
parent 0f52812767
commit b5da7ba233
10 changed files with 501 additions and 101 deletions

View File

@ -1,5 +1,19 @@
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const sharp_1 = __importDefault(require("sharp"));
const animated = __importStar(require("animated-gif-detector"));
const path_1 = require("path");
const fs_extra_1 = require("fs-extra");
const delay_1 = require("delay");
class FilmOut {
/**
@ -7,9 +21,13 @@ class FilmOut {
**/
constructor(display, ffmpeg, ffprobe, ui, light) {
this.id = 'filmout';
this.videoExtensions = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4'];
this.stillExtensions = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
this.gifExtension = '.gif';
this.state = {
frame: 0,
frames: 0,
still: false,
path: null,
fileName: null,
info: {},
@ -56,6 +74,9 @@ class FilmOut {
**/
async move() {
let start = +new Date();
if (this.state.still) {
return false;
}
if (this.state.dir) {
this.state.frame++;
}
@ -89,8 +110,8 @@ class FilmOut {
await delay_1.delay(20);
}
/**
*
**/
*
**/
async end() {
await delay_1.delay(20);
this.display.hide();
@ -100,26 +121,67 @@ class FilmOut {
*
**/
async onConnect(evt, arg) {
let info;
let frames = 0;
try {
info = await this.ffprobe.info(arg.path);
let isAnimated = false;
let info;
let ext;
ext = path_1.extname(arg.fileName.toLowerCase());
console.dir(arg);
console.log(ext);
if (ext === this.gifExtension) {
try {
isAnimated = await this.isGifAnimated(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
await this.ui.send(this.id, { valid: false });
return false;
}
this.state.still = !isAnimated;
}
catch (err) {
//this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
else if (this.stillExtensions.indexOf(ext) !== -1) {
this.state.still = true;
}
else if (this.videoExtensions.indexOf(ext) !== -1) {
this.state.still = false;
}
else {
this.log.error(`File is not of a valid file type`, 'FILMOUT', true, true);
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
if (this.state.still) {
try {
info = await this.stillInfo(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
frames = 1;
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
else {
try {
info = await this.ffprobe.info(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
}
console.dir(info);
this.state.frame = 0;
this.state.path = arg.path;
this.state.fileName = arg.fileName;
@ -130,6 +192,29 @@ class FilmOut {
this.state.enabled = true;
return await this.ui.send(this.id, { valid: true, state: JSON.stringify(this.state) });
}
/**
* Return true if gif is animated, false if it is a still
**/
async isGifAnimated(pathStr) {
let gifBuffer;
try {
gifBuffer = await fs_extra_1.readFile(pathStr);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
return false;
}
return animated(gifBuffer);
}
/**
* Return information on a still image using the sharp module
**/
async stillInfo(pathStr) {
return sharp_1.default(pathStr).metadata();
}
/**
*
**/
async previewFrame(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -144,6 +229,9 @@ class FilmOut {
}
this.ui.send('preview_frame', { path, frame: arg.frame });
}
/**
*
**/
async preview(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -164,6 +252,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async focus(evt, arg) {
this.log.info(`Showing focus screen`);
try {
@ -174,6 +265,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async field(evt, arg) {
this.log.info(`Showing field guide screen`);
try {
@ -184,6 +278,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async meter(evt, arg) {
this.log.info(`Showing meter screen`);
try {
@ -194,6 +291,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async close(evt, arg) {
try {
await this.display.hide();
@ -203,6 +303,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
onDisplay(evt, arg) {
this.display.change(arg.display);
this.log.info(`Changing the display to ${arg.display}`);

File diff suppressed because one or more lines are too long

View File

@ -34,6 +34,8 @@ let filmout;
class FilmOut {
constructor() {
this.id = 'filmout';
this.extensions = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4', '.gif',
'.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
this.displays = [];
this.state = {
frame: 0,
@ -99,13 +101,12 @@ class FilmOut {
$('#filmout_stats_monitor_size').text(`${display.width} x ${display.height}`);
$('#filmout_stats_monitor_aspect').text(`${aspect}`);
$('#filmout_stats_monitor_scale').text(`${parseFloat(display.scale).toFixed(1)} scale factor`);
console.dir(display);
//console.dir(display);
this.state.display = id;
ipcRenderer.send('display', { display: id });
}
selectFile() {
const elem = $('#digital');
const extensions = ['mpg', 'mpeg', 'mov', 'mkv', 'avi', 'mp4'];
dialog.showOpenDialog({
title: `Select video or image sequence`,
properties: [`openFile`],
@ -120,19 +121,18 @@ class FilmOut {
if (!files)
return false;
let valid = false;
let path = files[0];
let pathStr = files[0];
let displayName;
if (path && path !== '') {
for (let ext of extensions) {
if (path.toLowerCase().indexOf(`.${ext}`) !== -1) {
valid = true;
}
}
if (!valid)
let ext;
if (pathStr && pathStr !== '') {
ext = path.extname(pathStr.toLowerCase());
valid = this.extensions.indexOf(ext) === -1 ? false : true;
if (!valid) {
return false;
log.info(`Selected video ${path.split('/').pop()}`, 'DIGITAL', true);
elem.attr('data-file', path);
displayName = path.split('/').pop();
}
log.info(`Selected video ${pathStr.split('/').pop()}`, 'DIGITAL', true);
elem.attr('data-file', pathStr);
displayName = pathStr.split('/').pop();
elem.val(displayName);
$('#filmout_file').val(displayName);
}

View File

@ -6,6 +6,7 @@ const notifier = require('node-notifier');
const fs = require('fs');
const uuid = require('uuid').v4;
const moment = require('moment');
const path = require('path');
const humanizeDuration = require('humanize-duration');
const PACKAGE = require('./package.json');
const cfg = require('./data/cfg.json');

View File

@ -13,8 +13,12 @@ declare var proj : any;
declare var grid : any;
declare var dialog : any;
declare var ipcRenderer : any;
declare var path : any;
function gcd (a : number, b : number) {
/**
* Determine the greatest common denominator
*/
function gcd (a : number, b : number) : any {
if (b === 0) return a;
return gcd(b, a % b);
}
@ -49,6 +53,9 @@ let filmout : FilmOut;
class FilmOut {
private id : string = 'filmout';
private extensions : string[] = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4',
'.gif',
'.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
private displays : any[] = [];
private state : any = {
frame : 0,
@ -100,6 +107,7 @@ class FilmOut {
const w : number = display.width / scale;
const elem : any = $('#filmout_monitor');
const aspect : any = reduceRatio(display.width, display.height);
let h : number;
let top : number;
@ -120,13 +128,12 @@ class FilmOut {
$('#filmout_stats_monitor_size').text(`${display.width} x ${display.height}`);
$('#filmout_stats_monitor_aspect').text(`${aspect}`);
$('#filmout_stats_monitor_scale').text(`${parseFloat(display.scale).toFixed(1)} scale factor`);
console.dir(display);
//console.dir(display);
this.state.display = id;
ipcRenderer.send('display', { display : id });
}
selectFile () {
const elem : any = $('#digital');
const extensions : string[] = ['mpg', 'mpeg', 'mov', 'mkv', 'avi', 'mp4'];
dialog.showOpenDialog({
title : `Select video or image sequence`,
properties : [`openFile`], // openDirectory, multiSelection, openFile
@ -140,18 +147,18 @@ class FilmOut {
}, (files : string[]) => {
if (!files) return false;
let valid : boolean = false;
let path : string = files[0];
let pathStr : string = files[0];
let displayName : string;
if (path && path !== '') {
for (let ext of extensions) {
if (path.toLowerCase().indexOf(`.${ext}`) !== -1) {
valid = true;
}
let ext : string;
if (pathStr && pathStr !== '') {
ext = path.extname(pathStr.toLowerCase());
valid = this.extensions.indexOf(ext) === -1 ? false : true;
if (!valid) {
return false;
}
if (!valid) return false;
log.info(`Selected video ${path.split('/').pop()}`, 'DIGITAL', true);
elem.attr('data-file', path);
displayName = path.split('/').pop();
log.info(`Selected video ${pathStr.split('/').pop()}`, 'DIGITAL', true);
elem.attr('data-file', pathStr);
displayName = pathStr.split('/').pop();
elem.val(displayName);
$('#filmout_file').val(displayName);
}

View File

@ -1,5 +1,19 @@
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const sharp_1 = __importDefault(require("sharp"));
const animated = __importStar(require("animated-gif-detector"));
const path_1 = require("path");
const fs_extra_1 = require("fs-extra");
const delay_1 = require("delay");
class FilmOut {
/**
@ -7,9 +21,13 @@ class FilmOut {
**/
constructor(display, ffmpeg, ffprobe, ui, light) {
this.id = 'filmout';
this.videoExtensions = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4'];
this.stillExtensions = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
this.gifExtension = '.gif';
this.state = {
frame: 0,
frames: 0,
still: false,
path: null,
fileName: null,
info: {},
@ -56,6 +74,9 @@ class FilmOut {
**/
async move() {
let start = +new Date();
if (this.state.still) {
return false;
}
if (this.state.dir) {
this.state.frame++;
}
@ -89,8 +110,8 @@ class FilmOut {
await delay_1.delay(20);
}
/**
*
**/
*
**/
async end() {
await delay_1.delay(20);
this.display.hide();
@ -100,26 +121,67 @@ class FilmOut {
*
**/
async onConnect(evt, arg) {
let info;
let frames = 0;
try {
info = await this.ffprobe.info(arg.path);
let isAnimated = false;
let info;
let ext;
ext = path_1.extname(arg.fileName.toLowerCase());
console.dir(arg);
console.log(ext);
if (ext === this.gifExtension) {
try {
isAnimated = await this.isGifAnimated(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
await this.ui.send(this.id, { valid: false });
return false;
}
this.state.still = !isAnimated;
}
catch (err) {
//this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
else if (this.stillExtensions.indexOf(ext) !== -1) {
this.state.still = true;
}
else if (this.videoExtensions.indexOf(ext) !== -1) {
this.state.still = false;
}
else {
this.log.error(`File is not of a valid file type`, 'FILMOUT', true, true);
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
if (this.state.still) {
try {
info = await this.stillInfo(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
frames = 1;
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
else {
try {
info = await this.ffprobe.info(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
}
console.dir(info);
this.state.frame = 0;
this.state.path = arg.path;
this.state.fileName = arg.fileName;
@ -130,6 +192,29 @@ class FilmOut {
this.state.enabled = true;
return await this.ui.send(this.id, { valid: true, state: JSON.stringify(this.state) });
}
/**
* Return true if gif is animated, false if it is a still
**/
async isGifAnimated(pathStr) {
let gifBuffer;
try {
gifBuffer = await fs_extra_1.readFile(pathStr);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
return false;
}
return animated(gifBuffer);
}
/**
* Return information on a still image using the sharp module
**/
async stillInfo(pathStr) {
return sharp_1.default(pathStr).metadata();
}
/**
*
**/
async previewFrame(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -144,6 +229,9 @@ class FilmOut {
}
this.ui.send('preview_frame', { path, frame: arg.frame });
}
/**
*
**/
async preview(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -164,6 +252,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async focus(evt, arg) {
this.log.info(`Showing focus screen`);
try {
@ -174,6 +265,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async field(evt, arg) {
this.log.info(`Showing field guide screen`);
try {
@ -184,6 +278,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async meter(evt, arg) {
this.log.info(`Showing meter screen`);
try {
@ -194,6 +291,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async close(evt, arg) {
try {
await this.display.hide();
@ -203,6 +303,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
onDisplay(evt, arg) {
this.display.change(arg.display);
this.log.info(`Changing the display to ${arg.display}`);

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,19 @@
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const sharp_1 = __importDefault(require("sharp"));
const animated = __importStar(require("animated-gif-detector"));
const path_1 = require("path");
const fs_extra_1 = require("fs-extra");
const delay_1 = require("delay");
class FilmOut {
/**
@ -7,9 +21,13 @@ class FilmOut {
**/
constructor(display, ffmpeg, ffprobe, ui, light) {
this.id = 'filmout';
this.videoExtensions = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4'];
this.stillExtensions = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
this.gifExtension = '.gif';
this.state = {
frame: 0,
frames: 0,
still: false,
path: null,
fileName: null,
info: {},
@ -56,6 +74,9 @@ class FilmOut {
**/
async move() {
let start = +new Date();
if (this.state.still) {
return false;
}
if (this.state.dir) {
this.state.frame++;
}
@ -89,8 +110,8 @@ class FilmOut {
await delay_1.delay(20);
}
/**
*
**/
*
**/
async end() {
await delay_1.delay(20);
this.display.hide();
@ -100,26 +121,67 @@ class FilmOut {
*
**/
async onConnect(evt, arg) {
let info;
let frames = 0;
try {
info = await this.ffprobe.info(arg.path);
let isAnimated = false;
let info;
let ext;
ext = path_1.extname(arg.fileName.toLowerCase());
console.dir(arg);
console.log(ext);
if (ext === this.gifExtension) {
try {
isAnimated = await this.isGifAnimated(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
await this.ui.send(this.id, { valid: false });
return false;
}
this.state.still = !isAnimated;
}
catch (err) {
//this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
else if (this.stillExtensions.indexOf(ext) !== -1) {
this.state.still = true;
}
else if (this.videoExtensions.indexOf(ext) !== -1) {
this.state.still = false;
}
else {
this.log.error(`File is not of a valid file type`, 'FILMOUT', true, true);
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
if (this.state.still) {
try {
info = await this.stillInfo(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
frames = 1;
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
else {
try {
info = await this.ffprobe.info(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid: false });
return false;
}
}
console.dir(info);
this.state.frame = 0;
this.state.path = arg.path;
this.state.fileName = arg.fileName;
@ -130,6 +192,29 @@ class FilmOut {
this.state.enabled = true;
return await this.ui.send(this.id, { valid: true, state: JSON.stringify(this.state) });
}
/**
* Return true if gif is animated, false if it is a still
**/
async isGifAnimated(pathStr) {
let gifBuffer;
try {
gifBuffer = await fs_extra_1.readFile(pathStr);
}
catch (err) {
this.log.error(err, 'FILMOUT', true, true);
return false;
}
return animated(gifBuffer);
}
/**
* Return information on a still image using the sharp module
**/
async stillInfo(pathStr) {
return sharp_1.default(pathStr).metadata();
}
/**
*
**/
async previewFrame(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -144,6 +229,9 @@ class FilmOut {
}
this.ui.send('preview_frame', { path, frame: arg.frame });
}
/**
*
**/
async preview(evt, arg) {
const state = JSON.parse(JSON.stringify(this.state));
let path;
@ -164,6 +252,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async focus(evt, arg) {
this.log.info(`Showing focus screen`);
try {
@ -174,6 +265,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async field(evt, arg) {
this.log.info(`Showing field guide screen`);
try {
@ -184,6 +278,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async meter(evt, arg) {
this.log.info(`Showing meter screen`);
try {
@ -194,6 +291,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async close(evt, arg) {
try {
await this.display.hide();
@ -203,6 +303,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
onDisplay(evt, arg) {
this.display.change(arg.display);
this.log.info(`Changing the display to ${arg.display}`);

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,20 @@
'use strict';
import sharp from 'sharp';
import * as animated from 'animated-gif-detector';
import { extname } from 'path';
import { readFile } from 'fs-extra';
import { delay } from 'delay';
class FilmOut {
private id : string = 'filmout';
private videoExtensions : string[] = ['.mpg', '.mpeg', '.mov', '.mkv', '.avi', '.mp4'];
private stillExtensions : string[] = ['.tif', '.tiff', '.png', '.jpg', '.jpeg', '.bmp'];
private gifExtension : string = '.gif';
public state : any = {
frame : 0,
frames : 0,
still : false,
path : null,
fileName : null,
info : {},
@ -45,6 +53,7 @@ class FilmOut {
**/
private listen () {
this.ipc.on(this.id, this.onConnect.bind(this));
this.ipc.on('focus', this.focus.bind(this));
this.ipc.on('field', this.field.bind(this));
this.ipc.on('meter', this.meter.bind(this));
@ -64,6 +73,9 @@ class FilmOut {
**/
public async move () {
let start : number = +new Date();
if (this.state.still) {
return false;
}
if (this.state.dir) {
this.state.frame++;
} else {
@ -94,7 +106,7 @@ class FilmOut {
await this.display.show(this.state.frame);
await delay(20);
}
/**
/**
*
**/
private async end () {
@ -106,26 +118,64 @@ class FilmOut {
*
**/
async onConnect (evt : any, arg : any) {
let info;
let frames = 0;
let frames : number = 0;
let isAnimated : boolean = false;
let info : any;
let ext : string;
try {
info = await this.ffprobe.info(arg.path);
} catch (err) {
//this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid : false });
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid : false });
ext = extname(arg.fileName.toLowerCase());
console.dir(arg)
console.log(ext)
if (ext === this.gifExtension) {
try {
isAnimated = await this.isGifAnimated(arg.path);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
await this.ui.send(this.id, { valid : false });
return false;
}
this.state.still = !isAnimated;
} else if (this.stillExtensions.indexOf(ext) !== -1) {
this.state.still = true;
} else if (this.videoExtensions.indexOf(ext) !== -1) {
this.state.still = false;
} else {
this.log.error(`File is not of a valid file type`, 'FILMOUT', true, true);
return false;
}
if (this.state.still) {
try {
info = await this.stillInfo(arg.path);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid : false });
return false;
}
frames = 1;
} else {
try {
info = await this.ffprobe.info(arg.path);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid : false });
return false;
}
try {
frames = await this.ffprobe.frames(arg.path);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
this.state.enabled = false;
await this.ui.send(this.id, { valid : false });
return false;
}
}
console.dir(info)
this.state.frame = 0;
this.state.path = arg.path;
this.state.fileName = arg.fileName;
@ -137,7 +187,28 @@ class FilmOut {
this.state.enabled = true;
return await this.ui.send(this.id, { valid : true, state : JSON.stringify(this.state) });
}
/**
* Return true if gif is animated, false if it is a still
**/
async isGifAnimated (pathStr : string) {
let gifBuffer : Buffer;
try {
gifBuffer = await readFile(pathStr);
} catch (err) {
this.log.error(err, 'FILMOUT', true, true);
return false;
}
return animated(gifBuffer);
}
/**
* Return information on a still image using the sharp module
**/
async stillInfo (pathStr : string) {
return sharp(pathStr).metadata();
}
/**
*
**/
async previewFrame (evt : any, arg : any) {
const state : any = JSON.parse(JSON.stringify(this.state));
let path : string;
@ -152,7 +223,9 @@ class FilmOut {
}
this.ui.send('preview_frame', { path, frame : arg.frame })
}
/**
*
**/
async preview (evt : any, arg : any) {
const state : any = JSON.parse(JSON.stringify(this.state));
let path : string;
@ -174,7 +247,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async focus (evt : any, arg : any) {
this.log.info(`Showing focus screen`);
try {
@ -184,7 +259,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async field (evt : any, arg : any) {
this.log.info(`Showing field guide screen`);
try {
@ -194,7 +271,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async meter (evt : any, arg : any) {
this.log.info(`Showing meter screen`);
try {
@ -204,7 +283,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
async close (evt : any, arg : any) {
try {
await this.display.hide();
@ -213,7 +294,9 @@ class FilmOut {
this.log.error(err, 'FILMOUT', true, true);
}
}
/**
*
**/
onDisplay (evt : any, arg : any) {
this.display.change(arg.display);
this.log.info(`Changing the display to ${arg.display}`);