diff --git a/.gitignore b/.gitignore index 7eb40b0..3de71ef 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ *.mp3 *.gif *.webm +*.heic +*.heif converted-ss/ tmp-ss/ node_modules/ diff --git a/convertToAscii.js b/convertToAscii.js index 8e63e4b..e893141 100644 --- a/convertToAscii.js +++ b/convertToAscii.js @@ -1,63 +1,98 @@ -module.exports = convertToAscii = async (file = __dirname + 'input.png', output = __dirname + '/output.png', dotSize = 24, verticalSpacinModifier = 4, callback) => { - console.log('converting image to ascii'); - const hobbitImageFile = file; - const density = 'Ñ@#W$9876543210?!abc;:+=-,._ '; +const { createCanvas } = require("canvas"); +const ImageDataURI = require("image-data-uri"); +var sizeOf = require("image-size"); +const { exec, execSync } = require("child_process"); +const heicToPng = require("./heicToPng"); - const { createCanvas } = require('canvas') - const ImageDataURI = require('image-data-uri'); - var sizeOf = require('image-size'); - var dimensions = sizeOf(hobbitImageFile); +module.exports = convertToAscii = async ( + file = __dirname + "input.png", + output = __dirname + "/output.png", + dotSize = 24, + verticalSpacingModifier = 4, + scaledSize = 120, + callback +) => { + const filePNG = file + (file.toLowerCase().endsWith(".png") ? "" : ".png"); + let fileToConvert = file; + if ( + file.toLowerCase().endsWith(".heic") || + file.toLowerCase().endsWith(".heif") + ) { + console.log("heic file got"); + await heicToPng(file, filePNG); + fileToConvert = filePNG; + } + console.log("pre image resize"); + const scaledFile = "scaled-" + filePNG; + execSync( + `ffmpeg -i ${fileToConvert} -vf scale=${scaledSize}:-2 ${scaledFile} -y` + ); + console.log("post image scale"); - const hobbit = { - width: dimensions.width, - height: dimensions.height, - pixels: [], - } + await convert(scaledFile, output, dotSize, verticalSpacingModifier); + callback(output); +}; - function clamp(input, min, max) { - return input < min ? min : input > max ? max : input; - } +const convert = async (file, output, dotSize, verticalSpacingModifier) => { + const density = "Ñ@#W$9876543210?!abc;:+=-,._ "; + var dimensions = sizeOf(file); - function map(current, in_min, in_max, out_min, out_max) { - const mapped = ((current - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min; - return clamp(mapped, out_min, out_max); - } + const image = { + width: dimensions.width, + height: dimensions.height, + pixels: [], + }; - await new Promise((res, rej) => { - var PNG = require('png-js'); - PNG.decode(hobbitImageFile, function(pixels) { + function clamp(input, min, max) { + return input < min ? min : input > max ? max : input; + } - const canvas = createCanvas(hobbit.width * dotSize, hobbit.height * dotSize); - const ctx = canvas.getContext('2d') + function map(current, in_min, in_max, out_min, out_max) { + const mapped = + ((current - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min; + return clamp(mapped, out_min, out_max); + } - hobbit.pixels = pixels; + await new Promise((res, rej) => { + var PNG = require("png-js"); + PNG.decode(file, function (pixels) { + const canvas = createCanvas( + image.width * dotSize, + image.height * dotSize + ); + const ctx = canvas.getContext("2d"); - ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, hobbit.width * dotSize, hobbit.height * dotSize); - - ctx.font = (dotSize + verticalSpacinModifier) + "px Courier"; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = `white`; + image.pixels = pixels; - for(let x = 0; x < hobbit.width; x++) { - for(let y = 0; y < hobbit.height; y++) { - const pixelPosition = (x + y*hobbit.width)*4; - const r = hobbit.pixels[pixelPosition + 0]; - const g = hobbit.pixels[pixelPosition + 1]; - const b = hobbit.pixels[pixelPosition + 2]; - const a = hobbit.pixels[pixelPosition + 3]; - - const avg = Math.floor((r+g+b)/ 3) * (a/255); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, image.width * dotSize, image.height * dotSize); - const gray = map(255 - avg, 0, 255, 0, density.length); - ctx.fillText(density.charAt(gray), x*dotSize + dotSize/2, y*dotSize + dotSize/2); - } - } - - ImageDataURI.outputFile(canvas.toDataURL(), output); - res(1); - }); + ctx.font = dotSize + verticalSpacingModifier + "px Courier"; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillStyle = `white`; + + for (let x = 0; x < image.width; x++) { + for (let y = 0; y < image.height; y++) { + const pixelPosition = (x + y * image.width) * 4; + const r = image.pixels[pixelPosition + 0]; + const g = image.pixels[pixelPosition + 1]; + const b = image.pixels[pixelPosition + 2]; + const a = image.pixels[pixelPosition + 3]; + + const avg = Math.floor((r + g + b) / 3) * (a / 255); + + const gray = map(255 - avg, 0, 255, 0, density.length); + ctx.fillText( + density.charAt(gray), + x * dotSize + dotSize / 2, + y * dotSize + dotSize / 2 + ); + } + } + + ImageDataURI.outputFile(canvas.toDataURL(), output); + res(1); }); - callback(output); -} + }); +}; diff --git a/heicToPng.js b/heicToPng.js new file mode 100644 index 0000000..cb94d12 --- /dev/null +++ b/heicToPng.js @@ -0,0 +1,12 @@ +const { promisify } = require("util"); +const fs = require("fs"); +const convert = require("heic-convert"); + +module.exports = async function heicToPng(input, output) { + const inputBuffer = await promisify(fs.readFile)(input); + const outputBuffer = await convert({ + buffer: inputBuffer, + format: "PNG", + }); + await promisify(fs.writeFile)(output, outputBuffer); +}; diff --git a/index.js b/index.js index d678c01..47d697d 100644 --- a/index.js +++ b/index.js @@ -21,10 +21,10 @@ const convertToAscii = require("./convertToAscii"); const extractFrames = require("./extractFrames"); const gifToMp4 = require("./gifToMp4"); const scaleVideo = require("./scaleVideo"); -const fs = require('fs'); +const fs = require("fs"); const makeVideoFromImages = require("./makeVideoFromImages"); const mp4ToGif = require("./mp4ToGif"); -const fsExtra = require('fs-extra'); +const fsExtra = require("fs-extra"); args = process.argv; @@ -37,277 +37,350 @@ const randomName = (Math.random() + 1).toString(36).substring(2); const action = args.shift(); -let usage = ''; -let example = ''; - +let usage = ""; +let example = ""; let input; let output; let pixelSize; -let pixelModifyer; +let pixelModifier; 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); - }); +const _scaleVideo = ( + inputFile, + pixelSize, + pixelModifier, + 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, + pixelModifier, + scaledSize, + () => { + 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); - } - }); - }) - }); -} + ); + } + 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': + 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`; - 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[0] === 'help') { - console.log(`${usage}\n${example}`); - process.exit(0); - } + if (args.length > 5) { + console.error(`Invalid parameter count!\n${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[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[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); + } - convertToAscii(args[0], args[1], args[2], args[3], () => { - console.log(`Image converted and saved in ${args[1]}`); - }); + input = args[0]; + output = args[1]; + pixelSize = parseInt(args[2], base); + pixelModifier = parseInt(args[3], base); + scaledSize = parseInt(args[4], base); + + convertToAscii(input, output, pixelSize, pixelModifier, scaledSize, () => { + console.log(`Image converted and saved in ${args[1]}`); + }); break; - case 'gif:gif': + 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`; - 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[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.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[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[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[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); + } - 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); + pixelModifier = parseInt(args[3], base); + scaledSize = parseInt(args[4], base); + fps = parseInt(args[5], base); - 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); - }); + gifToMp4(input, "gif-to-mp4-" + randomName + ".mp4", (convertedFile) => { + _scaleVideo( + convertedFile, + pixelSize, + pixelModifier, + scaledSize, + fps, + output, + true, + true + ); + }); break; - case 'gif:mp4': + 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`; - 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[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.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[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[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[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); + } - 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); + pixelModifier = parseInt(args[3], base); + scaledSize = parseInt(args[4], base); + fps = parseInt(args[5], base); - 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); + gifToMp4(input, "gif-to-mp4-" + randomName + ".mp4", (convertedFile) => { + _scaleVideo( + convertedFile, + pixelSize, + pixelModifier, + scaledSize, + fps, + output, + false, + true + ); + }); break; - case 'mp4:mp4': + 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`; - 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[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.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[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[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[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); + } - 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); + pixelModifier = parseInt(args[3], base); + scaledSize = parseInt(args[4], base); + fps = parseInt(args[5], base); - 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, + pixelModifier, + 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`; - _scaleVideo(input, pixelSize, pixelModifyer, scaledSize, fps, output, false, false); + 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); + pixelModifier = parseInt(args[3], base); + scaledSize = parseInt(args[4], base); + fps = parseInt(args[5], base); + + _scaleVideo( + input, + pixelSize, + pixelModifier, + scaledSize, + fps, + output, + false, + false + ); break; - default: -console.log(`Available commands: + 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 diff --git a/package.json b/package.json index e647e90..41f835d 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,13 @@ "license": "ISC", "dependencies": { "canvas": "^2.9.0", + "ffmpeg": "0.0.4", "ffmpeg-extract-frames": "^2.0.2", "fs-extra": "^10.0.0", + "heic-convert": "^1.2.4", "image-data-uri": "^2.0.1", "image-size": "^1.0.1", - "png-js": "^1.0.0" + "png-js": "^1.0.0", + "util": "^0.12.4" } } diff --git a/readme.md b/readme.md index f078dd4..ff6880e 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ ## Commands ### Options + - input-file - file to be converted (original is kept) - default: input.mp4/input.gif/input.png depending on command used @@ -52,4 +53,4 @@ ### Convert PNG to ASCII PNG -`npm run convert:img [input-file] [output-file] [pixel-size] [font-size-modifier]` +`npm run convert:img [input-file] [output-file] [pixel-size] [font-size-modifier] [scaled-size]`