'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.FFPROBE = void 0; const promises_1 = require("fs/promises"); const path_1 = require("path"); const shell_1 = require("../shell"); const log_1 = require("../log"); /** * Class representing all ffprobe features. */ class FFPROBE { constructor(bin = 'ffprobe') { this.bin = bin; this.log = (0, log_1.createLog)('ffprobe2'); } async exists(path) { try { await (0, promises_1.access)(path); return true; } catch { return false; } } /** * Parse the fps entry into a float representing the fps of a video **/ parseFps(fpsStr) { let fps = 30.0; let parts; if (fpsStr.indexOf('/') !== -1) { parts = fpsStr.split('/'); fps = parseFloat(parts[0]) / parseFloat(parts[1]); } else { fps = parseFloat(fpsStr); } return fps; } /** * Get info on a video in json format. Use for filmout. * * @param {string} video Path to video * * @returns {object} Video info in an object **/ async info(video) { const cmd = [ this.bin, '-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', video ]; let fileExists; let raw; let json; let vid; //whether video has stream with video data try { fileExists = await this.exists(video); } catch (err) { this.log.error(`Error checking if ${video} exists`, err); } if (!fileExists) { this.log.error(new Error(`File ${video} does not exist`)); return null; } try { raw = await this.exec(cmd); } catch (err) { this.log.error('Error getting info', err); return null; } try { json = JSON.parse(raw); } catch (err) { this.log.error('Error parsing stdout', err); this.log.error(raw); return raw; } if (json.format && json.format.duration) { json.seconds = parseFloat(json.format.duration); } if (json && json.streams) { vid = json.streams.find((stream) => { if (stream.width && stream.height) return stream; }); } if (vid) { json.width = vid.width; json.height = vid.height; json.fps = this.parseFps(vid.r_frame_rate); } return json; } async exec(cmd) { return new Promise(async (resolve, reject) => { function after(lines) { return resolve(lines); } const child = new shell_1.Shell(cmd, null, null, null, after, true); await child.execute(); }); } /** * Count the number of frames in the video using one of two methods. * The first uses -select_streams and is very fast. The second uses * -count_frames and is VERY slow. * * @param {string} video Path to video * * @returns {integer} Number of frames in video **/ async frames(video) { const ext = (0, path_1.extname)(video.toLowerCase()); let cmd = [ this.bin, '-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=nb_frames', '-of', 'default=nokey=1:noprint_wrappers=1', video ]; let backup_cmd = [ this.bin, '-v', 'error', '-count_frames', '-select_streams', 'v:0', '-show_entries', 'stream=nb_read_frames', '-of', 'default=nokey=1:noprint_wrappers=1', video ]; let fileExists; let raw; let frames; try { fileExists = await this.exists(video); } catch (err) { this.log.error('Error checking if file exists', err); return false; } if (!fileExists) { this.log.error(new Error(`File ${video} does not exist`)); return false; } if (ext === '.mkv') { cmd = backup_cmd; } try { raw = await this.exec(cmd); } catch (err) { this.log.error(err); return false; } try { frames = parseInt(raw.stdout); } catch (err) { return raw.stdout; } return frames; } } exports.FFPROBE = FFPROBE; /* function map (obj : any) { console.dir(obj); } */ module.exports = { FFPROBE }; //# sourceMappingURL=index.js.map