1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- import { spawn } from 'child_process';
- import { existsSync, statSync } from 'fs';
- import { getLogger } from './loggers';
- const logger = getLogger('gifski');
- const sizeLimit = 10 * 2 ** 20;
- const roundToEven = (n: number) => Math.ceil(n / 2) * 2;
- export default async (inputFilePath: string, targetWidth?: number) => {
- const outputFilePath = inputFilePath.replace(/(?:\.[^.]*)?$/, '.gif')
- try {
- const args = [
- inputFilePath,
- '-o',
- outputFilePath,
- '--fps',
- '12.5',
- '--quiet',
- '--quality',
- '90',
- ];
- if (typeof(targetWidth) === 'number') {
- args.push('--width', roundToEven(targetWidth).toString());
- }
- logger.info(` gifski ${args.join(' ')}`);
- const gifskiSpawn = spawn('gifski', args);
- const gifskiResult = new Promise<string>((resolve, reject) => {
- const sizeChecker = setInterval(() => {
- if (existsSync(outputFilePath) && statSync(outputFilePath).size > sizeLimit) gifskiSpawn.kill();
- }, 5000);
- gifskiSpawn.on('exit', () => {
- clearInterval(sizeChecker);
- if (!existsSync(outputFilePath) || statSync(outputFilePath).size === 0) return reject('no file was created on exit');
- logger.info(`gif conversion succeeded, file path: ${outputFilePath}`);
- resolve(outputFilePath);
- });
- });
- const stderr = [];
- gifskiSpawn.stderr.on('data', errdata => stderr.push(errdata));
- gifskiSpawn.stderr.on('end', () => {
- if (stderr.length !== 0) {
- if (!gifskiSpawn.killed) gifskiSpawn.kill();
- throw Error(Buffer.concat(stderr).toString());
- }
- });
- return await gifskiResult;
- } catch (error) {
- logger.error(`error converting video to gif ${error ? `message: ${error}` : ''}`);
- throw Error('error converting video to gif');
- }
- };
|