diff --git a/.gitignore b/.gitignore index 0168bd6..585b92c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,8 @@ node_modules *.log *.mp4 *.webm -*.exe \ No newline at end of file +*.exe +*.zip +.gitignore +settings.json +*test* \ No newline at end of file diff --git a/index.js b/index.js index 2cb5d26..48e50ee 100644 --- a/index.js +++ b/index.js @@ -1,52 +1,193 @@ const fs = require('fs') const { exec, execSync } = require('child_process') -const readline = require("readline") -const { stdout, stderr } = require('process') const cliProgress = require('cli-progress') -const { finished } = require('stream') +const term = require("terminal-kit").terminal -//Create terminal readlines - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}) +/** + * TODO : Adapt audio quality as well to accomodate long videos(Currently 5m is too much) + * FIND A WAY TO COMPILE THIS:.. + */ //Parse file inputs (Drag n drop or arguments) inputList = process.argv.slice(2) input = inputList[0] - -file = input.split("\\") -file = file[file.length - 1] - -fileType = file.split(".")[1] - -if (fileType == "jpg" || fileType == "JPG" || fileType == "png" || fileType == "PNG" || fileType == "webp") { - //encodePicture(input) -} -else if (fileType == "webm" || fileType == "mp4" || fileType == "mov" || fileType == "mkv" || fileType == "avi") { - encodeVideo(input, file.split(".")[0]) +let file, fileType, bar1 +//if launched without params +if (!input) { + startMenu() } else { - console.log("Unsupported format") - rl.question("press enter to exit...", () => { process.exit() }) - process.exit() + file = input.split("\\") + file = file[file.length - 1] + + fileType = file.split(".")[1] + + if (!fs.existsSync(input)) { + term.italic(`${input}`).bold.red(" <- Path or File doesn't exist\n") + term.grey("press enter to exit...") + term.inputField(function () { process.exit() }) + } + else { + bar1 = new cliProgress.SingleBar({ + synchronousUpdate: true, + align: "left", + hideCursor: true + }, cliProgress.Presets.shades_classic) + + if (fileType == "jpg" || fileType == "JPG" || fileType == "png" || fileType == "PNG" || fileType == "webp") { + encodePicture(input, file.split(".")[0]) + } + else if (fileType == "webm" || fileType == "mp4" || fileType == "mov" || fileType == "mkv" || fileType == "avi") { + encodeVideo(input, file.split(".")[0]) + } + else if ("ogg" || "mp3" || "aiff" || "wav" || "flac") { + encodeAudio(input, file.split(".")[0]) + } + else { + term.italic(`${file}`).bold.red(` <- Unsupported format\n`) + term.grey("press enter to exit...") + term.inputField(function () { process.exit() }) + } + } } -//create progress bar -const bar1 = new cliProgress.SingleBar({ - synchronousUpdate: true, - align: "left", - hideCursor: true -}, cliProgress.Presets.shades_classic) +async function encodeVideo(path, out) { + //create progress bar + const [command, presetName, duration, isTwoPass] = await constructVideoCommand(path, out) + bar1.start(duration, 0, { speed: "N/A" }) + let isPastHalf = false + let encoder = exec(command) + encoder.stderr.on("data", (chunk) => { + currentTime = chunk.split("time=")[1]?.split(" ")[0] + if (currentTime) { + const arr = currentTime.split(":") // splitting the string by colon + let seconds = Number.parseFloat(arr[0] * 3600 + arr[1] * 60 + (+arr[2])) // converting to s -async function getDuration(file) { - let result = await ffprobe(file) - result = result.split("Duration: ")[1].split(",")[0] - const arr = result.split(":") // splitting the string by colon + console.clear() + //If 2nd pass add that portion in + console.log(`Encoding ${out}.webm with "${presetName}" preset...`) + if (isTwoPass) { + if (seconds / 2 >= (duration - 0.2) / 2) isPastHalf = true + isPastHalf ? bar1.update(Math.round(seconds * 50) / 100 + (duration / 2)) : bar1.update(Math.round(seconds * 50) / 100) + } + else { + bar1.update(Math.round(seconds * 100) / 100) + } + } + }) + + encoder.on("close", () => { + console.clear() + bar1.stop() + fs.rm("ffmpeg2pass-0.log", (error) => { error }) + term.bold.green("Finished!\n") + term.grey("press enter to exit...\n") + term.inputField(() => { process.exit() }) + }) +} +async function encodeAudio(path, out) { + let [duration, resolution] = await getDurationAndResolution(path) + const bitrateLimit = Math.round(62000 / duration) + + bar1.start(duration, 0, { speed: "N/A" }) + + const encoder = exec(`ffmpeg -y -i "${path}" -c:a libvorbis -b:a ${bitrateLimit}k ${out}.ogg`) + + encoder.stderr.on("data", (chunk) => { + currentTime = chunk.split("time=")[1]?.split(" ")[0] + if (currentTime) { + const arr = currentTime.split(":") + let seconds = Number.parseFloat(arr[0] * 3600 + arr[1] * 60 + (+arr[2])) // converting to s + console.clear() + console.log(`Encoding ${out}.ogg`) + bar1.update(Math.round(seconds * 100) / 100) + } + }) + encoder.on("close", () => { + console.clear() + term.bold.green("Finished!\n") + term.grey("press enter to exit...\n") + term.inputField(() => { process.exit() }) + }) +} + +async function encodePicture(path, out) { + const encoder = exec(`ffmpeg -y -i "${path}" -qscale 80 -compression_level 6 ${out}.webp`) + encoder.stderr.on("data", (chunk) => { + console.clear() + term.yellow(`Encoding ${out}.webp...`) + + }) + encoder.on("close", () => { + console.clear() + term.bold.green("Finished!\n") + term.grey("press enter to exit...\n") + term.inputField(() => { process.exit() }) + }) +} + +async function constructVideoCommand(path, out) { + + //gets settings file, if doesnt exist makes a new file and uses those defaults + let settings = await getSettings().catch(async (err) => { + settings = undefined + }) + if (!settings) settings = await makeNewSettingsFile() + settings = JSON.parse(settings.toString()) + settings = settings.presets[settings.currentSetting] + + let [duration, resolutionHeight] = await getDurationAndResolution(path) + //Calculates video bitrate to fit right under 8mb @224kb vorbis audio bitrate + const bitrateLimit = Math.round((62000 - (224 * duration)) / duration) + + let command = "" + let crfIndex = 0 + let isTwoPass = true + while (resolutionHeight > settings.crfMap[crfIndex].resolution) { + crfIndex++ + //if the resolution is still higher, just use highest res + if (!settings.crfMap[crfIndex]?.resolution) { + crfIndex-- + break + } + } + + for (pass = 1; pass <= 2; pass++) { + command += `ffmpeg -y -i "${path}" -vcodec libvpx-vp9 -acodec libvorbis -qscale:a 7 ` + command += `-deadline ${settings.deadline} ` + command += `-cpu-used ${settings.cpuUsed} ` + if (settings?.minrate) { + command += `-b:v ${Math.round(bitrateLimit * 0.95)}k ` + command += `-minrate ${Math.round(bitrateLimit / 100 * settings.minrate)}k ` + command += `-maxrate ${bitrateLimit}k ` + } + else { + command += `-b:v ${bitrateLimit}k ` + command += `-crf ${settings.crfMap[crfIndex].crf} ` + } + //realtime doesnt support two pass + if (settings.deadline == "realtime") { + command += `-row-mt 1 "${out}.webm"` + isTwoPass = false + break + } + pass == 1 ? command += `-pass 1 -row-mt 1 -f webm NUL && ` : command += `-pass 2 -row-mt 1 "${out}.webm" ` + } + return [command, settings.name, duration, isTwoPass] +} + +async function getDurationAndResolution(file) { + let query = await ffprobe(file) + //duration in seconds + duration = query.split("Duration: ")[1].split(",")[0] + const arr = duration.split(":") // splitting the string by colon const seconds = arr[0] * 3600 + arr[1] * 60 + (+arr[2]) // converting to s - return Number.parseFloat(seconds) + + //resolution height + resolutionHeight = query.split("Stream #0:0")[1]?.split(",")[2].split(" ")[1].split("x")[1] + + return [Number.parseFloat(seconds), resolutionHeight] } function ffprobe(file) { @@ -57,40 +198,226 @@ function ffprobe(file) { }) } -async function encodeVideo(path, out) { - //Calculates video bitrate to fit right under 8mb @224kb vorbis audio bitrate - duration = await getDuration(input) - bitrateLimit = Math.round(7776 / duration) - console.log(`compressing ${path} to ${out}.webm at ${bitrateLimit}K's`) - const encoder = exec(`ffmpeg.exe -y -i "${path}" -vcodec libvpx-vp9 -acodec libvorbis -qscale:a 7 -cpu-used 3 -crf 20 -b:v ${bitrateLimit}k -pass 1 -f webm NUL && ffmpeg.exe -y -i "${path}" -vcodec libvpx-vp9 -acodec libvorbis -qscale:a 7 -cpu-used 3 -crf 20 -b:v ${bitrateLimit}k -pass 2 "${out}.webm"`) - bar1.start(duration, 0, { speed: "N/A" }) - - let isPastHalf = false - encoder.stderr.on("data", (chunk) => { - currentTime = chunk.split("time=")[1]?.split(" ")[0] - if (currentTime) { - const arr = currentTime.split(":") // splitting the string by colon - let seconds = Number.parseFloat(arr[0] * 3600 + arr[1] * 60 + (+arr[2])) // converting to s - - console.clear() - console.log(`Encoding ${out}.webm...`) - //If 2nd pass add that portion in - if (seconds / 2 >= (duration - 0.2) / 2) isPastHalf = true - isPastHalf ? bar1.update(Math.round(seconds * 50) / 100 + (duration / 2)) : bar1.update(Math.round(seconds * 50) / 100) - } - }) - encoder.on("close", () => { - console.clear() - bar1.stop() - fs.rm("ffmpeg2pass-0.log", (error) => { error }) - console.log("Finished!") - rl.question("press enter to exit...", () => { process.exit() }) - }) - encoder.on("exit", () => { - console.clear() - bar1.stop() - fs.rm("ffmpeg2pass-0.log", (error) => { error }) - console.log("Finished!") - rl.question("press enter to exit...", () => { process.exit() }) +function getSettings() { + return new Promise((resolve, reject) => { + getSettings = fs.readFile("settings.json", (err, data) => { + resolve(data) + reject(err) + }) }) } + +async function startMenu() { + console.clear() + //gets settings file, if doesnt exist makes a new file and uses those defaults + let settings = await getSettings().catch(async (err) => { + settings = undefined + }) + if (!settings) settings = await makeNewSettingsFile() + + settings = JSON.parse(settings.toString()) + let menu = [] + for (i = 0; i < settings.presets.length; i++) { + menu.push(`${i}. ${settings.presets[i].name}`) + } + term.italic("How to convert: [app] [filename.extension]\n") + term.yellow("Hello! This menu is for selecting performance/speed preset.\n") + term.yellow("Currently using ").bgMagenta(`"${settings.presets[settings.currentSetting].name}"`).yellow(" preset") + term.singleColumnMenu(menu, (error, response) => { + settings.currentSetting = response.selectedIndex + fs.writeFileSync("settings.json", JSON.stringify(settings)) + term.green("\n Using").green.bold(` ${settings.presets[settings.currentSetting].name} `).green("setting\n") + term.grey("Press enter to exit...") + term.inputField(() => { process.exit() }) + }) +} + +function makeNewSettingsFile() { + const settings = ` + { + "currentSetting": 2, + "presets": [{ + "name": "Most efficient 8 megabytes of your life", + "cpuUsed": 0, + "deadline": "best", + "minrate": 90, + "crfMap": [{ + "resolution": 240, + "crf": 1 + }, + { + "resolution": 360, + "crf": 1 + }, + { + "resolution": 480, + "crf": 1 + }, + { + "resolution": 720, + "crf": 1 + }, + { + "resolution": 1080, + "crf": 1 + }, + { + "resolution": 1440, + "crf": 1 + }, + { + "resolution": 2160, + "crf": 1 + } + ] + }, + { + "name": "I have some time to kill", + "cpuUsed": 1, + "deadline": "good", + "minrate": 75, + "crfMap": [{ + "resolution": 240, + "crf": 20 + }, + { + "resolution": 360, + "crf": 20 + }, + { + "resolution": 480, + "crf": 20 + }, + { + "resolution": 720, + "crf": 20 + }, + { + "resolution": 1080, + "crf": 17 + }, + { + "resolution": 1440, + "crf": 15 + }, + { + "resolution": 2160, + "crf": 10 + } + ] + }, + { + "name": "Mid", + "cpuUsed": 3, + "deadline": "good", + "minrate":75, + "crfMap": [{ + "resolution": 240, + "crf": 30 + }, + { + "resolution": 360, + "crf": 30 + }, + { + "resolution": 480, + "crf": 30 + }, + { + "resolution": 720, + "crf": 25 + }, + { + "resolution": 1080, + "crf": 20 + }, + { + "resolution": 1440, + "crf": 15 + }, + { + "resolution": 2160, + "crf": 10 + } + ] + }, + { + "name": "I don't like waiting", + "cpuUsed": 4, + "deadline": 100, + "minrate": 90, + "crfMap": [{ + "resolution": 240, + "crf": 45 + }, + { + "resolution": 360, + "crf": 42 + }, + { + "resolution": 480, + "crf": 40 + }, + { + "resolution": 720, + "crf": 35 + }, + { + "resolution": 1080, + "crf": 30 + }, + { + "resolution": 1440, + "crf": 25 + }, + { + "resolution": 2160, + "crf": 20 + } + ] + }, + { + "name": "I want it, NOW!", + "cpuUsed": 4, + "deadline": "realtime", + "minrate": 50, + "crfMap": [{ + "resolution": 240, + "crf": 40 + }, + { + "resolution": 360, + "crf": 35 + }, + { + "resolution": 480, + "crf": 30 + }, + { + "resolution": 720, + "crf": 25 + }, + { + "resolution": 1080, + "crf": 20 + }, + { + "resolution": 1440, + "crf": 15 + }, + { + "resolution": 2160, + "crf": 10 + } + ] + } + + ] +} + ` + return new Promise((resolve, reject) => { + fs.writeFile("settings.json", settings, () => { + resolve(settings) + }) + }) +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 09f692e..391a8bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,12 @@ "license": "ISC", "dependencies": { "cli-progress": "^3.11.0", - "pkg": "^5.6.0" + "pkg": "^5.6.0", + "require-runtime": "^2.0.0", + "terminal-kit": "^2.4.0" + }, + "bin": { + "discord-media-compressor-8mb": "index.js" } }, "node_modules/@babel/helper-validator-identifier": { @@ -44,6 +49,19 @@ "node": ">=6.9.0" } }, + "node_modules/@cronvel/get-pixels": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@cronvel/get-pixels/-/get-pixels-3.4.0.tgz", + "integrity": "sha512-do5jDoX9oCR/dGHE4POVQ3PYDCmQ2Fow4CA72UL4WoE8zUImA/0lChczjfl+ucNjE4sXFWUnzoO6j4WzrUvLnw==", + "dependencies": { + "jpeg-js": "^0.4.1", + "ndarray": "^1.0.19", + "ndarray-pack": "^1.1.1", + "node-bitmap": "0.0.1", + "omggif": "^1.0.10", + "pngjs": "^5.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -235,6 +253,11 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, "node_modules/cli-progress": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.0.tgz", @@ -370,6 +393,14 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cwise-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", + "integrity": "sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=", + "dependencies": { + "uniq": "^1.0.0" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -738,6 +769,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/iota-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", + "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "node_modules/is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", @@ -792,6 +833,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "node_modules/jpeg-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", + "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -803,6 +849,14 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/lazyness": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lazyness/-/lazyness-1.2.0.tgz", + "integrity": "sha512-KenL6EFbwxBwRxG93t0gcUyi0Nw0Ub31FJKN1laA4UscdkL1K1AxUd0gYZdcLU3v+x+wcFi4uQKS5hL+fk500g==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -913,6 +967,32 @@ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, + "node_modules/ndarray": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz", + "integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==", + "dependencies": { + "iota-array": "^1.0.0", + "is-buffer": "^1.0.2" + } + }, + "node_modules/ndarray-pack": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ndarray-pack/-/ndarray-pack-1.2.1.tgz", + "integrity": "sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo=", + "dependencies": { + "cwise-compiler": "^1.1.2", + "ndarray": "^1.0.13" + } + }, + "node_modules/nextgen-events": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.5.2.tgz", + "integrity": "sha512-0ZEIRQywH5Oxt2IYYufRltQg/KjXhKM7f7MHve+ZIRaKnIR1PPYEXAl2WBmej5Sf0Qh2GgE/21sMRZVuOyxLzw==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/node-abi": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", @@ -929,6 +1009,14 @@ "semver": "bin/semver" } }, + "node_modules/node-bitmap": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-bitmap/-/node-bitmap-0.0.1.tgz", + "integrity": "sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE=", + "engines": { + "node": ">=v0.6.5" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -975,6 +1063,11 @@ "node": ">=0.10.0" } }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1082,6 +1175,14 @@ "pkg-fetch": "lib-es5/bin.js" } }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/prebuild-install": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", @@ -1193,6 +1294,11 @@ "node": ">=0.10.0" } }, + "node_modules/require-runtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-runtime/-/require-runtime-2.0.0.tgz", + "integrity": "sha512-wyRTcpojuIr2LNb+0DkKjpz0mr2lMntLYs0pRyA/Fp1Qi5OHU0Jg42VdOQC01tW2VGmEQP8wJLZ5FXfgnbmQjA==" + }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -1264,6 +1370,22 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "node_modules/seventh": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/seventh/-/seventh-0.7.40.tgz", + "integrity": "sha512-7sxUydQx4iEh17uJUFjZDAwbffJirldZaNIJvVB/hk9mPEL3J4GpLGSL+mHFH2ydkye46DAsLGqzFJ+/Qj5foQ==", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=7.6.0" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -1331,6 +1453,14 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/string-kit": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/string-kit/-/string-kit-0.16.3.tgz", + "integrity": "sha512-1G5lfH1DbuSd+G9kba+uKKXxDWuRCwHJPIp88rBpSD0QzS0UYo/rquiefUFLM/mymH40QUt9Zxt0vEZYGzbyzA==", + "engines": { + "node": ">=14.15.0" + } + }, "node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -1424,6 +1554,24 @@ "node": ">= 6" } }, + "node_modules/terminal-kit": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/terminal-kit/-/terminal-kit-2.4.0.tgz", + "integrity": "sha512-lQCKNFYCaVoFM23pcurnQ7wOnsz4u588JNu2sfNOnB8IU6Tl4vdOdHNe7bL2aIiB0kA7m94gS4VI0+3CRI1G/A==", + "dependencies": { + "@cronvel/get-pixels": "^3.4.0", + "chroma-js": "^2.1.2", + "lazyness": "^1.2.0", + "ndarray": "^1.0.19", + "nextgen-events": "^1.5.2", + "seventh": "^0.7.40", + "string-kit": "^0.16.0", + "tree-kit": "^0.7.4" + }, + "engines": { + "node": ">=14.15.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -1448,6 +1596,11 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "node_modules/tree-kit": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/tree-kit/-/tree-kit-0.7.4.tgz", + "integrity": "sha512-Of3tPmVs3b6BhzyUJ7t0olisf47kYr9qAm0XaUpURMjdBn6TwiVaaMuTFoKkkvPGojd9trKAHlrGGcGKcdR1DA==" + }, "node_modules/tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -1475,6 +1628,11 @@ "node": ">= 0.8.0" } }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -1678,6 +1836,19 @@ "to-fast-properties": "^2.0.0" } }, + "@cronvel/get-pixels": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@cronvel/get-pixels/-/get-pixels-3.4.0.tgz", + "integrity": "sha512-do5jDoX9oCR/dGHE4POVQ3PYDCmQ2Fow4CA72UL4WoE8zUImA/0lChczjfl+ucNjE4sXFWUnzoO6j4WzrUvLnw==", + "requires": { + "jpeg-js": "^0.4.1", + "ndarray": "^1.0.19", + "ndarray-pack": "^1.1.1", + "node-bitmap": "0.0.1", + "omggif": "^1.0.10", + "pngjs": "^5.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1804,6 +1975,11 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, + "chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, "cli-progress": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.11.0.tgz", @@ -1910,6 +2086,14 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "cwise-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", + "integrity": "sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=", + "requires": { + "uniq": "^1.0.0" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2174,6 +2358,16 @@ "p-is-promise": "^3.0.0" } }, + "iota-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", + "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "is-core-module": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", @@ -2213,6 +2407,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "jpeg-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", + "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==" + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -2222,6 +2421,11 @@ "universalify": "^2.0.0" } }, + "lazyness": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/lazyness/-/lazyness-1.2.0.tgz", + "integrity": "sha512-KenL6EFbwxBwRxG93t0gcUyi0Nw0Ub31FJKN1laA4UscdkL1K1AxUd0gYZdcLU3v+x+wcFi4uQKS5hL+fk500g==" + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -2299,6 +2503,29 @@ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, + "ndarray": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz", + "integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==", + "requires": { + "iota-array": "^1.0.0", + "is-buffer": "^1.0.2" + } + }, + "ndarray-pack": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ndarray-pack/-/ndarray-pack-1.2.1.tgz", + "integrity": "sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo=", + "requires": { + "cwise-compiler": "^1.1.2", + "ndarray": "^1.0.13" + } + }, + "nextgen-events": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.5.2.tgz", + "integrity": "sha512-0ZEIRQywH5Oxt2IYYufRltQg/KjXhKM7f7MHve+ZIRaKnIR1PPYEXAl2WBmej5Sf0Qh2GgE/21sMRZVuOyxLzw==" + }, "node-abi": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", @@ -2314,6 +2541,11 @@ } } }, + "node-bitmap": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-bitmap/-/node-bitmap-0.0.1.tgz", + "integrity": "sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE=" + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -2343,6 +2575,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2421,6 +2658,11 @@ "yargs": "^16.2.0" } }, + "pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==" + }, "prebuild-install": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", @@ -2500,6 +2742,11 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-runtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-runtime/-/require-runtime-2.0.0.tgz", + "integrity": "sha512-wyRTcpojuIr2LNb+0DkKjpz0mr2lMntLYs0pRyA/Fp1Qi5OHU0Jg42VdOQC01tW2VGmEQP8wJLZ5FXfgnbmQjA==" + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -2541,6 +2788,19 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "seventh": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/seventh/-/seventh-0.7.40.tgz", + "integrity": "sha512-7sxUydQx4iEh17uJUFjZDAwbffJirldZaNIJvVB/hk9mPEL3J4GpLGSL+mHFH2ydkye46DAsLGqzFJ+/Qj5foQ==", + "requires": { + "setimmediate": "^1.0.5" + } + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -2588,6 +2848,11 @@ "safe-buffer": "~5.1.0" } }, + "string-kit": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/string-kit/-/string-kit-0.16.3.tgz", + "integrity": "sha512-1G5lfH1DbuSd+G9kba+uKKXxDWuRCwHJPIp88rBpSD0QzS0UYo/rquiefUFLM/mymH40QUt9Zxt0vEZYGzbyzA==" + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -2659,6 +2924,21 @@ } } }, + "terminal-kit": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/terminal-kit/-/terminal-kit-2.4.0.tgz", + "integrity": "sha512-lQCKNFYCaVoFM23pcurnQ7wOnsz4u588JNu2sfNOnB8IU6Tl4vdOdHNe7bL2aIiB0kA7m94gS4VI0+3CRI1G/A==", + "requires": { + "@cronvel/get-pixels": "^3.4.0", + "chroma-js": "^2.1.2", + "lazyness": "^1.2.0", + "ndarray": "^1.0.19", + "nextgen-events": "^1.5.2", + "seventh": "^0.7.40", + "string-kit": "^0.16.0", + "tree-kit": "^0.7.4" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -2677,6 +2957,11 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "tree-kit": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/tree-kit/-/tree-kit-0.7.4.tgz", + "integrity": "sha512-Of3tPmVs3b6BhzyUJ7t0olisf47kYr9qAm0XaUpURMjdBn6TwiVaaMuTFoKkkvPGojd9trKAHlrGGcGKcdR1DA==" + }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -2698,6 +2983,11 @@ "prelude-ls": "~1.1.2" } }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", diff --git a/package.json b/package.json index 9a82133..d71b125 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "discord-media-compressor-8mb", - "version": "1.0.0", - "description": "helps free discord users to send any media and not get bottlenecked by discords 8mb file limit", + "version": "1.0.1", + "description": "helps free discord users to send any media(image, video, audio) and not get limited by discords 8mb file limit", "main": "index.js", + "bin": "./index.js", "scripts": { "start": "node index.js", - "build": "pkg -t latest-win-x64 index.js" + "build": "pkg -t --compress GZip package.json" }, "keywords": [ "discord", @@ -17,6 +18,15 @@ "license": "ISC", "dependencies": { "cli-progress": "^3.11.0", - "pkg": "^5.6.0" + "pkg": "^5.6.0", + "require-runtime": "^2.0.0", + "terminal-kit": "^2.4.0" + }, + "pkg": { + "scripts": "index.js", + "targets": [ + "latest-win-x64" + ], + "outputPath": "" } -} +} \ No newline at end of file