/* PREREQUISITES: - ffmpeg installed and added to the PATH COMMANDS TO PREPARE VIDEO FOR CONVERSION: - scale video and lower fps ffmpeg.exe -i .\original-video.mp4 -vf "scale=120:-2, fps=30" scaled-video.mp4 COMMANDS TO BUILD VIDEO AFTER CONVERSION: - extract audio from video ffmpeg -i .\original-video.mp4 extracted-audio.mp3 - combine video with audio ffmpeg -i .\converted-video.mp4 -i extracted-audio.mp3 -c:v copy -c:a aac finished-video.mp4 - convert video to gif (no audio) ffmpeg -i .\converted-video.mp4 -f gif .\converted-video.gif */ const convertToAscii = require("./convertToAscii"); const extractFrames = require("./extractFrames"); const gifToMp4 = require("./gifToMp4"); const scaleVideo = require("./scaleVideo"); const fs = require('fs'); const makeVideoFromImages = require("./makeVideoFromImages"); const mp4ToGif = require("./mp4ToGif"); const fsExtra = require('fs-extra'); args = process.argv; args.shift(); args.shift(); const base = 10; const randomName = (Math.random() + 1).toString(36).substring(2); const action = args.shift(); let usage = ''; let example = ''; let input; let output; let pixelSize; let pixelModifyer; let scaledSize; let fps; const _scaleVideo = (inputFile, pixelSize, pixelModifyer, scaledSize, fps, output, convertToGif = false, deleteInputFile = false) => { scaleVideo(inputFile, 'mp4-scaled-' + randomName + '.mp4', scaledSize, fps, (scaledFile) => { if (deleteInputFile) { fs.rmSync(inputFile); } const outputFolder = __dirname + '/extracted-frames-'+randomName; extractFrames(scaledFile, outputFolder, async () => { fs.rmSync(scaledFile); let files = fs.readdirSync(outputFolder); const convertedFolder = __dirname + '/converted-frames-'+randomName; let index = 0; for (let file of files) { index++; await convertToAscii(outputFolder + '/' + file, convertedFolder + '/' + file, pixelSize, pixelModifyer, () => { console.log(index, '/', files.length); fs.rmSync(outputFolder + '/' + file); }); } fsExtra.emptyDirSync(outputFolder); fs.rmdirSync(outputFolder); makeVideoFromImages(convertedFolder + '/%d.png', __dirname + 'generated-video-' + randomName + '.mp4', fps, fps, (generatedVideoFIle) => { fsExtra.emptyDirSync(convertedFolder); fs.rmdirSync(convertedFolder); if (convertToGif) { mp4ToGif(generatedVideoFIle, output, (gif) => { console.log('gif generated in: ' + gif); }); } else { fs.renameSync(generatedVideoFIle, output); console.log('video generated in: ' + output); } }); }) }); } switch (action) { case 'img': usage = `Usage: npm run convert:img input-image-path.png[optional, default:./input.png] output-image-path.png[optional, default:./output.png] pixel-size[optional, default:24] font-size-modifier[optional, degault:4]`; example = `Example: npm run convert:img input.png output.png 24 0`; if (args[0] === 'help') { console.log(`${usage}\n${example}`); process.exit(0); } if (args.length > 4) { console.error(`Invalid parameter count!\n${usage}\n${example}`); process.exit(0); } if (args[2] && isNaN(parseInt(args[2], base))) { console.error(`Pixel size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[3] && isNaN(parseInt(args[3], base))) { console.error(`Font size modifier must be a number!\n${usage}\n${example}`); process.exit(0); } convertToAscii(args[0], args[1], args[2], args[3], () => { console.log(`Image converted and saved in ${args[1]}`); }); break; case 'gif:gif': usage = `Usage: npm run convert:gif:gif input-image-path.png[optional, default:./input.gif] output-image-path.png[optional, default:./output.gif] pixel-size[optional, default:24] font-size-modifier[optional, degault:4] scaled-size[optional, default=120] fps[optional, default=10]`; example = `Example: npm run convert:gif:gif input.gif output.gif 24 4 120 10`; if (args[0] === 'help') { console.log(`${usage}\n${example}`); process.exit(0); } if (args.length > 7) { console.error(`Invalid parameter count!\n${usage}\n${example}`); process.exit(0); } if (args[2] && isNaN(parseInt(args[2], base))) { console.error(`Pixel size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[3] && isNaN(parseInt(args[3], base))) { console.error(`Font size modifier must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[4] && isNaN(parseInt(args[4], base))) { console.error(`Scaled size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[5] && isNaN(parseInt(args[5], base))) { console.error(`Original FPS must be a number!\n${usage}\n${example}`); process.exit(0); } input = args[0]; output = args[1]; pixelSize = parseInt(args[2], base); pixelModifyer = parseInt(args[3], base); scaledSize = parseInt(args[4], base); fps = parseInt(args[5], base); gifToMp4(input, 'gif-to-mp4-'+randomName+'.mp4', (convertedFile) => { _scaleVideo(convertedFile, pixelSize, pixelModifyer, scaledSize, fps, output, true, true); }); break; case 'gif:mp4': usage = `Usage: npm run convert:gif:mp4 input-image-path.gif[optional, default:./input.gif] output-image-path.mp4[optional, default:./output.mp4] pixel-size[optional, default:24] font-size-modifier[optional, degault:4] scaled-size[optional, default=120] fps[optional, default=10]`; example = `Example: npm run convert:gif:mp4 input.gif output.mp4 24 4 120 10`; if (args[0] === 'help') { console.log(`${usage}\n${example}`); process.exit(0); } if (args.length > 7) { console.error(`Invalid parameter count!\n${usage}\n${example}`); process.exit(0); } if (args[2] && isNaN(parseInt(args[2], base))) { console.error(`Pixel size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[3] && isNaN(parseInt(args[3], base))) { console.error(`Font size modifier must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[4] && isNaN(parseInt(args[4], base))) { console.error(`Scaled size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[5] && isNaN(parseInt(args[5], base))) { console.error(`Original FPS must be a number!\n${usage}\n${example}`); process.exit(0); } input = args[0]; output = args[1]; pixelSize = parseInt(args[2], base); pixelModifyer = parseInt(args[3], base); scaledSize = parseInt(args[4], base); fps = parseInt(args[5], base); gifToMp4(input, 'gif-to-mp4-'+randomName+'.mp4', (convertedFile) => { _scaleVideo(convertedFile, pixelSize, pixelModifyer, scaledSize, fps, output, false, true); }); break; case 'mp4:gif': usage = `Usage: npm run convert:mp4:gif input-image-path.mp4[optional, default:./input.mp4] output-image-path.gif[optional, default:./output.gif] pixel-size[optional, default:24] font-size-modifier[optional, degault:4] scaled-size[optional, default=120] fps[optional, default=10]`; example = `Example: npm run convert:mp4:gif input.mp4 output.gif 24 4 120 10`; if (args[0] === 'help') { console.log(`${usage}\n${example}`); process.exit(0); } if (args.length > 7) { console.error(`Invalid parameter count!\n${usage}\n${example}`); process.exit(0); } if (args[2] && isNaN(parseInt(args[2], base))) { console.error(`Pixel size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[3] && isNaN(parseInt(args[3], base))) { console.error(`Font size modifier must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[4] && isNaN(parseInt(args[4], base))) { console.error(`Scaled size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[5] && isNaN(parseInt(args[5], base))) { console.error(`Original FPS must be a number!\n${usage}\n${example}`); process.exit(0); } input = args[0]; output = args[1]; pixelSize = parseInt(args[2], base); pixelModifyer = parseInt(args[3], base); scaledSize = parseInt(args[4], base); fps = parseInt(args[5], base); _scaleVideo(input, pixelSize, pixelModifyer, scaledSize, fps, output, true, false); break; case 'mp4:mp4': usage = `Usage: npm run convert:mp4:mp4 input-image-path.mp4[optional, default:./input.mp4] output-image-path.mp4[optional, default:./output.mp4] pixel-size[optional, default:24] font-size-modifier[optional, degault:4] scaled-size[optional, default=120] fps[optional, default=10]`; example = `Example: npm run convert:mp4:mp4 input.mp4 output.mp4 24 4 120 10`; if (args[0] === 'help') { console.log(`${usage}\n${example}`); process.exit(0); } if (args.length > 7) { console.error(`Invalid parameter count!\n${usage}\n${example}`); process.exit(0); } if (args[2] && isNaN(parseInt(args[2], base))) { console.error(`Pixel size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[3] && isNaN(parseInt(args[3], base))) { console.error(`Font size modifier must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[4] && isNaN(parseInt(args[4], base))) { console.error(`Scaled size must be a number!\n${usage}\n${example}`); process.exit(0); } if (args[5] && isNaN(parseInt(args[5], base))) { console.error(`Original FPS must be a number!\n${usage}\n${example}`); process.exit(0); } input = args[0]; output = args[1]; pixelSize = parseInt(args[2], base); pixelModifyer = parseInt(args[3], base); scaledSize = parseInt(args[4], base); fps = parseInt(args[5], base); _scaleVideo(input, pixelSize, pixelModifyer, scaledSize, fps, output, false, false); break; default: console.log(`Available commands: convert:gif:gif - converts regular gif to ascii gif convert:gif:mp4 - converts regular gif to ascii mp4 convert:mp4:mp4 - converts regular mp4 to ascii mp4 convert:mp4:gif - converts regular mp4 to ascii gif convert:img - converts regular image to ascii image\n`); }