multifile support, added all filetypes, precision
This commit is contained in:
parent
981f8804f9
commit
57fdf245e1
11 changed files with 900 additions and 431 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -4,6 +4,8 @@ node_modules
|
||||||
*.webm
|
*.webm
|
||||||
*.exe
|
*.exe
|
||||||
*.zip
|
*.zip
|
||||||
.gitignore
|
*.webp
|
||||||
|
*.ogg
|
||||||
settings.json
|
settings.json
|
||||||
*test*
|
/testing ground/
|
||||||
|
/bin/index regular terminal.js
|
2
.npmrc
Normal file
2
.npmrc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
loglevel=silent
|
11
README.md
11
README.md
|
@ -6,4 +6,15 @@ Easy to use: Just drag a file on the executable and off it goes!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
How to install(Windows with binaries):
|
||||||
|
1. make a folder in `C:\Program Files` called "DMC", put release binaries and [ffmpeg windows full-build executables](https://github.com/GyanD/codexffmpeg/releases/) into `C:\Program Files\DMC\`
|
||||||
|
2. Add ffmpeg to PATH: `[Win BTN] + R`, type `SystemPropertiesAdvanced`, click `Environment Variables`, under "User variables for (user)" find variable Path, click on it and edit, in the now open window click `new`, and paste `C:\Program Files\DMC\`.
|
||||||
|
3. If the command `ffmpeg` in cmd works, you can now drag and drop files onto the binary and have it work!
|
||||||
|
4. to set performance preset, doubleclick the binary
|
||||||
|
|
||||||
|
How to install(Windows, Linux, MacOS):
|
||||||
|
1. get node.js from [here](https://nodejs.org)
|
||||||
|
2. clone repo into any folder you like.
|
||||||
|
3. run `npm install --save` to get all dependencies
|
||||||
|
4. run `npm install -g {PATH_TO_PROJECT_FOLDER}`
|
||||||
*might have bugs, currently videos only and windows only. Future plans will include audio: .ogg, and photos: .webm*
|
*might have bugs, currently videos only and windows only. Future plans will include audio: .ogg, and photos: .webm*
|
||||||
|
|
121
bin/index.js
Normal file
121
bin/index.js
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import fs from 'fs'
|
||||||
|
import { Encoder } from "../lib/encoder.js"
|
||||||
|
import { UI } from "../lib/ui.js"
|
||||||
|
import termkit from "terminal-kit"
|
||||||
|
import { SettingsManager } from "../lib/settingsManager.js"
|
||||||
|
import path from "path"
|
||||||
|
//get settings
|
||||||
|
let settings = new SettingsManager()
|
||||||
|
await settings.start()
|
||||||
|
let resolve = path.resolve
|
||||||
|
let term = termkit.terminal
|
||||||
|
const ui = new UI(settings.settings, settings.currentSetting)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : Adapt audio quality as well to accomodate long videos(Currently 5m is too much)
|
||||||
|
* FIND A WAY TO COMPILE THIS:..
|
||||||
|
*/
|
||||||
|
|
||||||
|
const inputList = process.argv.slice(2)
|
||||||
|
//if launched without params
|
||||||
|
if (!inputList[0]) {
|
||||||
|
ui.startMenu() //stops program here
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parse file inputs (n Drag n drop or arguments)
|
||||||
|
let filePaths = [], fileNames = [], fileTypes = []
|
||||||
|
let presetIndexArg = undefined
|
||||||
|
//if preset argument go through list from 2 and add argument
|
||||||
|
if (inputList[0] == "-preset") {
|
||||||
|
presetIndexArg = inputList[1]
|
||||||
|
|
||||||
|
for (let i = 2; i < inputList.length; i++) {
|
||||||
|
let file
|
||||||
|
file = resolve(inputList[i])
|
||||||
|
|
||||||
|
filePaths.push(file)
|
||||||
|
|
||||||
|
file = file.split("\\")
|
||||||
|
file = file[file.length - 1]
|
||||||
|
file = file.split(".")
|
||||||
|
|
||||||
|
fileTypes.push(file[1])
|
||||||
|
fileNames.push(file[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let i = 0; i < inputList.length; i++) {
|
||||||
|
let file
|
||||||
|
file = resolve(inputList[i])
|
||||||
|
|
||||||
|
filePaths.push(file)
|
||||||
|
|
||||||
|
file = file.split("\\")
|
||||||
|
file = file[file.length - 1]
|
||||||
|
file = file.split(".")
|
||||||
|
|
||||||
|
fileTypes.push(file[1])
|
||||||
|
fileNames.push(file[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main()
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
|
||||||
|
//file checks
|
||||||
|
let isListEncodable = true
|
||||||
|
//check if all files exist
|
||||||
|
for (let i = 0; i < filePaths.length; i++) {
|
||||||
|
if (!fs.existsSync(filePaths[i])) {
|
||||||
|
term.italic(`${filePaths[i]}`).bold.red(" <- Path or File doesn't exist\n")
|
||||||
|
term.grey("press enter to exit...")
|
||||||
|
isListEncodable = false
|
||||||
|
term.inputField(function () { process.exit() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if all files are valid formats
|
||||||
|
if (isListEncodable) {
|
||||||
|
for (let i = 0; i < filePaths.length; i++) {
|
||||||
|
if (fileTypes[i] == "jpg" || fileTypes[i] == "JPG" || fileTypes[i] == "png" || fileTypes[i] == "PNG" || fileTypes[i] == "webp" ||
|
||||||
|
fileTypes[i] == "webm" || fileTypes[i] == "mp4" || fileTypes[i] == "mov" || fileTypes[i] == "mkv" || fileTypes[i] == "avi" ||
|
||||||
|
fileTypes[i] == "ogg" || fileTypes[i] == "mp3" || fileTypes[i] == "aiff" || fileTypes[i] == "wav" || fileTypes[i] == "flac") {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
term.italic(`${fileTypes[i]}`).bold.red(` <- Unsupported format\n`)
|
||||||
|
term.grey("press enter to exit...")
|
||||||
|
isListEncodable = false
|
||||||
|
term.inputField(function () { process.exit() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//start encoding all
|
||||||
|
if (isListEncodable) {
|
||||||
|
|
||||||
|
let encoder = []
|
||||||
|
for (let i = 0; i < filePaths.length; i++) {
|
||||||
|
encoder.push(new Encoder(settings.settings, settings.currentSetting, presetIndexArg))
|
||||||
|
console.log(`Encoding with "${settings.currentSetting.name}" preset...`)
|
||||||
|
|
||||||
|
if (fileTypes[i] == "jpg" || fileTypes[i] == "JPG" || fileTypes[i] == "png" || fileTypes[i] == "PNG" || fileTypes[i] == "webp") {
|
||||||
|
ui.newBar(await encoder[i].encodePicture(filePaths[i], fileNames[i]))
|
||||||
|
ui.updateBar("time=00:00:01", i, false, true)
|
||||||
|
encoder[i].on("close", () => { ui.encodeFinished(i) })
|
||||||
|
}
|
||||||
|
else if (fileTypes[i] == "webm" || fileTypes[i] == "mp4" || fileTypes[i] == "mov" || fileTypes[i] == "mkv" || fileTypes[i] == "avi") {
|
||||||
|
ui.newBar(await encoder[i].encodeVideo(filePaths[i], fileNames[i]))
|
||||||
|
encoder[i].on("update", (chunk) => { ui.updateBar(chunk, i) })
|
||||||
|
encoder[i].on("close", () => { ui.encodeFinished(i) })
|
||||||
|
}
|
||||||
|
else if (fileTypes[i] == "ogg" || fileTypes[i] == "mp3" || fileTypes[i] == "aiff" || fileTypes[i] == "wav" || fileTypes[i] == "flac") {
|
||||||
|
ui.newBar(await encoder[i].encodeAudio(filePaths[i], fileNames[i]))
|
||||||
|
encoder[i].on("update", (chunk) => { ui.updateBar(chunk, i, false) })
|
||||||
|
encoder[i].on("close", () => { ui.encodeFinished(i) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
26
fieldTest.cjs
Normal file
26
fieldTest.cjs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
const child_process = require("child_process")
|
||||||
|
const FileHound = require('filehound')
|
||||||
|
|
||||||
|
let exec = child_process.exec
|
||||||
|
|
||||||
|
let command = "npm run start"
|
||||||
|
let testFiles = FileHound.create()
|
||||||
|
.path("testing ground")
|
||||||
|
.findSync()
|
||||||
|
|
||||||
|
testFiles.forEach((value, index) => {
|
||||||
|
console.log(value, index)
|
||||||
|
command += ` "${value}"`
|
||||||
|
})
|
||||||
|
console.log(command)
|
||||||
|
let test = exec(command)
|
||||||
|
test.stdout.on("data", (chunk) => {
|
||||||
|
console.log(chunk)
|
||||||
|
})
|
||||||
|
test.stderr.on("data", (chunk) => {
|
||||||
|
console.log(chunk)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.on("close", () => {
|
||||||
|
console.log("finished")
|
||||||
|
})
|
423
index.js
423
index.js
|
@ -1,423 +0,0 @@
|
||||||
const fs = require('fs')
|
|
||||||
const { exec, execSync } = require('child_process')
|
|
||||||
const cliProgress = require('cli-progress')
|
|
||||||
const term = require("terminal-kit").terminal
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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]
|
|
||||||
let file, fileType, bar1
|
|
||||||
//if launched without params
|
|
||||||
if (!input) {
|
|
||||||
startMenu()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
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() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
//resolution height
|
|
||||||
resolutionHeight = query.split("Stream #0:0")[1]?.split(",")[2].split(" ")[1].split("x")[1]
|
|
||||||
|
|
||||||
return [Number.parseFloat(seconds), resolutionHeight]
|
|
||||||
}
|
|
||||||
|
|
||||||
function ffprobe(file) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
exec(`ffprobe "${file}"`, (error, stdout, stderr) => {
|
|
||||||
resolve(stderr)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
138
lib/encoder.js
Normal file
138
lib/encoder.js
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
import { exec } from 'child_process'
|
||||||
|
|
||||||
|
export class Encoder {
|
||||||
|
currentSetting
|
||||||
|
settings
|
||||||
|
encoder
|
||||||
|
encodePresetIndexArg
|
||||||
|
constructor(settings, currentSetting, encodePresetIndexArg = undefined) {
|
||||||
|
this.settings = settings
|
||||||
|
this.currentSetting = currentSetting
|
||||||
|
this.encodePresetIndexArg = encodePresetIndexArg
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} path absolute path to file
|
||||||
|
* @param {String} out output filename
|
||||||
|
* @returns [duration, isTwoPass]
|
||||||
|
*/
|
||||||
|
async encodeVideo(path, out) {
|
||||||
|
//create progress bar
|
||||||
|
const [command, duration, isTwoPass] = await this.#constructVideoCommand(path, out)
|
||||||
|
this.encoder = exec(command)
|
||||||
|
return [duration, out, isTwoPass]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} path absolute path to file
|
||||||
|
* @param {String} out output filename
|
||||||
|
* @returns duration
|
||||||
|
*/
|
||||||
|
async encodeAudio(path, out) {
|
||||||
|
let [duration, resolution] = await this.#getDurationAndResolution(path)
|
||||||
|
const videoBitRate = Math.round(62000 / duration)
|
||||||
|
this.encoder = exec(`ffmpeg -y -i "${path}" -c:a libvorbis -b:a ${videoBitRate}k ${out}.ogg`)
|
||||||
|
return [duration, out, undefined]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} path absolute path to file
|
||||||
|
* @param {String} out output filename
|
||||||
|
*/
|
||||||
|
async encodePicture(path, out) {
|
||||||
|
this.encoder = exec(`ffmpeg -y -i "${path}" -qscale 80 -compression_level 6 ${out}.webp`)
|
||||||
|
return [1, out, undefined]
|
||||||
|
}
|
||||||
|
|
||||||
|
async #constructVideoCommand(path, out) {
|
||||||
|
let [duration, resolutionHeight] = await this.#getDurationAndResolution(path)
|
||||||
|
|
||||||
|
//Calculates video bitrate to fit right under 8mb 2:6 audio:video
|
||||||
|
const audioBitRate = Math.round(62000 / 8 * 2 / duration)
|
||||||
|
const videoBitRate = Math.round(62000 / 8 * 6 / duration)
|
||||||
|
|
||||||
|
//if command had argument of anotehr quality setting change to use that setting
|
||||||
|
if (this.encodePresetIndexArg) {
|
||||||
|
this.currentSetting = this.settings.presets[this.encodePresetIndexArg]
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = ""
|
||||||
|
let crfIndex = 0
|
||||||
|
let isTwoPass = true
|
||||||
|
//Compares current video height to CRFMAP to determine optimal CRF
|
||||||
|
while (resolutionHeight > this.currentSetting.crfMap[crfIndex].resolution) {
|
||||||
|
crfIndex++
|
||||||
|
//if the resolution is still higher, just use highest res
|
||||||
|
if (!this.currentSetting.crfMap[crfIndex]?.resolution) {
|
||||||
|
crfIndex--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let pass = 1; pass <= 2; pass++) {
|
||||||
|
command += `ffmpeg -y -i "${path}" -vcodec libvpx-vp9 -acodec libvorbis `
|
||||||
|
command += `-deadline ${this.currentSetting.deadline} `
|
||||||
|
command += `-cpu-used ${this.currentSetting.cpuUsed} `
|
||||||
|
if (this.currentSetting?.minrate) {
|
||||||
|
command += `-b:v ${Math.round(videoBitRate * 0.95)}k `
|
||||||
|
command += `-minrate ${Math.round(videoBitRate / 100 * this.currentSetting.minrate)}k `
|
||||||
|
command += `-maxrate ${videoBitRate}k `
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command += `-b:v ${videoBitRate}k `
|
||||||
|
command += `-b:a ${audioBitRate}k `
|
||||||
|
command += `-crf ${this.currentSetting.crfMap[crfIndex].crf} `
|
||||||
|
}
|
||||||
|
//realtime doesnt support two pass
|
||||||
|
if (this.currentSetting.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, duration, isTwoPass]
|
||||||
|
}
|
||||||
|
|
||||||
|
async #getDurationAndResolution(file) {
|
||||||
|
let query = await this.#ffprobe(file)
|
||||||
|
//duration in seconds
|
||||||
|
const 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
|
||||||
|
|
||||||
|
//resolution height
|
||||||
|
const resolutionHeight = query.split("Stream #0:0")[1]?.split(",")[2].split(" ")[1].split("x")[1]
|
||||||
|
|
||||||
|
return [Number.parseFloat(seconds), resolutionHeight]
|
||||||
|
}
|
||||||
|
|
||||||
|
#ffprobe(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(`ffprobe "${file}"`, (error, stdout, stderr) => {
|
||||||
|
resolve(stderr)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
on(channel, callback) {
|
||||||
|
switch (channel) {
|
||||||
|
case "close":
|
||||||
|
this.encoder.on("close", () => {
|
||||||
|
callback(true)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
case "update":
|
||||||
|
this.encoder.stderr.on("data", (chunk) => {
|
||||||
|
callback(chunk)
|
||||||
|
})
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new Error("Incorrect Channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
221
lib/settingsManager.js
Normal file
221
lib/settingsManager.js
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
import fs from "fs"
|
||||||
|
|
||||||
|
export class SettingsManager {
|
||||||
|
|
||||||
|
settings
|
||||||
|
currentSetting
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
await this.#init()
|
||||||
|
}
|
||||||
|
|
||||||
|
async #init() {
|
||||||
|
this.settings = await this.#getSettings().catch(async (err) => {
|
||||||
|
this.settings = undefined
|
||||||
|
})
|
||||||
|
if (!this.settings) this.settings = await this.#makeNewSettingsFile()
|
||||||
|
this.settings = JSON.parse(this.settings.toString())
|
||||||
|
this.currentSetting = this.settings.presets[this.settings.currentSetting]
|
||||||
|
}
|
||||||
|
async #getSettings() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getSettings = fs.readFile("settings.json", (err, data) => {
|
||||||
|
resolve(data)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async #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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
121
lib/ui.js
Normal file
121
lib/ui.js
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
import termkit from "terminal-kit"
|
||||||
|
import cliProgress from "cli-progress"
|
||||||
|
import fs from "fs"
|
||||||
|
|
||||||
|
export class UI {
|
||||||
|
term
|
||||||
|
bars = []
|
||||||
|
multibar
|
||||||
|
settings
|
||||||
|
currentSetting
|
||||||
|
|
||||||
|
constructor(settings, currentSetting) {
|
||||||
|
this.term = termkit.terminal
|
||||||
|
|
||||||
|
this.multibar = new cliProgress.MultiBar({
|
||||||
|
format: '[{bar}] {percentage}% | output: "{filename}" | ETA: {eta}s | {value}/{total}',
|
||||||
|
align: "left",
|
||||||
|
hideCursor: true,
|
||||||
|
autopadding: true,
|
||||||
|
}, cliProgress.Presets.shades_grey)
|
||||||
|
|
||||||
|
this.settings = settings
|
||||||
|
this.currentSetting = currentSetting
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Number} duration Duration of the encoded media
|
||||||
|
* @param {String} filename name of the encoding file
|
||||||
|
* @param {Boolean} isTwoPass is the encoded media two pass
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async newBar(encoderOutput) {
|
||||||
|
let duration = encoderOutput[0]
|
||||||
|
let filename = encoderOutput[1]
|
||||||
|
let isTwoPass = encoderOutput[2]
|
||||||
|
this.bars.push({
|
||||||
|
"bar": this.multibar.create(duration, 0, { speed: "N/A" }),
|
||||||
|
"isTwoPass": isTwoPass,
|
||||||
|
"isPastHalf": false,
|
||||||
|
"filename": filename,
|
||||||
|
"duration": duration,
|
||||||
|
"finished": false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const barIndex = this.bars.length - 1
|
||||||
|
return barIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateBar(chunk, barIndex = 0, isVideo = true, isImage = false) {
|
||||||
|
if (!chunk) return
|
||||||
|
if (isImage) {
|
||||||
|
this.bars[barIndex]?.bar.update(1, { filename: `${this.bars[barIndex].filename}.webp` })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isVideo) {
|
||||||
|
const currentTime = chunk.split("time=")[1]?.split(" ")[0]
|
||||||
|
if (!currentTime) return
|
||||||
|
const arr = currentTime.split(":")
|
||||||
|
let seconds = Number.parseFloat(arr[0] * 3600 + arr[1] * 60 + (+arr[2])) // converting to s
|
||||||
|
|
||||||
|
//If 2 pass divide bar into two parts to show both in progress in one progress
|
||||||
|
if (this.bars[barIndex].isTwoPass) {
|
||||||
|
if (seconds / 2 >= (this.bars[barIndex].duration - 0.2) / 2) this.bars[barIndex].isPastHalf = true
|
||||||
|
|
||||||
|
if (this.bars[barIndex].isPastHalf) this.bars[barIndex].bar.update(Math.round(seconds * 50) / 100 + (this.bars[barIndex].duration / 2), { filename: `${this.bars[barIndex].filename}.webm` })
|
||||||
|
else this.bars[barIndex].bar.update(Math.round(seconds * 50) / 100, { filename: `${this.bars[barIndex].filename}.webm` })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.bars[barIndex].bar.update(Math.round(seconds * 100) / 100, { filename: `${this.bars[barIndex].filename}.webm` })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const currentTime = chunk.split("time=")[1]?.split(" ")[0]
|
||||||
|
if (!currentTime) return
|
||||||
|
const arr = currentTime.split(":")
|
||||||
|
let seconds = Number.parseFloat(arr[0] * 3600 + arr[1] * 60 + (+arr[2])) // converting to s
|
||||||
|
this.bars[barIndex].bar.update(Math.round(seconds * 100) / 100, { filename: `${this.bars[barIndex].filename}.ogg` })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeFinished(barIndex) {
|
||||||
|
this.bars[barIndex].fininshed = true
|
||||||
|
// if all are finished stop multibars and exit
|
||||||
|
for (let i = 0; i < this.bars.length; i++) {
|
||||||
|
if (this.bars[i].finished) return
|
||||||
|
}
|
||||||
|
this.multibar.stop()
|
||||||
|
fs.rm("ffmpeg2pass-0.log", (error) => { error })
|
||||||
|
console.clear()
|
||||||
|
this.term.bold.green("Finished!\n")
|
||||||
|
this.term.grey("press enter to exit...\n")
|
||||||
|
this.term.inputField(() => { process.exit() })
|
||||||
|
}
|
||||||
|
|
||||||
|
async startMenu() {
|
||||||
|
await this.#menu()
|
||||||
|
}
|
||||||
|
async #menu() {
|
||||||
|
console.clear()
|
||||||
|
let menu = []
|
||||||
|
for (let i = 0; i < settings.presets.length; i++) {
|
||||||
|
menu.push(`${i}. ${settings.presets[i].name}`)
|
||||||
|
}
|
||||||
|
this.term("How to convert: [app] [optional: -preset {Index}] [filename.extension(s)]\n")
|
||||||
|
this.term("examples: \n")
|
||||||
|
this.term.italic(" npx DMC -preset 0 file.mp3 file4.mov img.jpg\n")
|
||||||
|
this.term.italic(" DMC.exe -preset 2 file34.wav file2.mp3\n\n")
|
||||||
|
this.term.yellow("Hello! This menu is for selecting performance/speed preset.\n")
|
||||||
|
this.term.yellow("Currently using ").bgMagenta(`"${settings.presets[settings.currentSetting].name}"`).yellow(" preset")
|
||||||
|
this.term.singleColumnMenu(menu, (error, response) => {
|
||||||
|
currentSetting = response.selectedIndex
|
||||||
|
fs.writeFileSync("settings.json", JSON.stringify(settings))
|
||||||
|
this.term.green("\n Using").green.bold(` ${settings.presets[settings.currentSetting].name} `).green("setting\n")
|
||||||
|
this.term.grey("Press enter to exit...")
|
||||||
|
this.term.inputField(() => { process.exit() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
251
package-lock.json
generated
251
package-lock.json
generated
|
@ -1,21 +1,22 @@
|
||||||
{
|
{
|
||||||
"name": "discord-media-compressor-8mb",
|
"name": "discord-media-compressor-8mb",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "discord-media-compressor-8mb",
|
"name": "discord-media-compressor-8mb",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cli-progress": "^3.11.0",
|
"cli-progress": "^3.11.0",
|
||||||
|
"filehound": "^1.17.6",
|
||||||
"pkg": "^5.6.0",
|
"pkg": "^5.6.0",
|
||||||
"require-runtime": "^2.0.0",
|
"require-runtime": "^2.0.0",
|
||||||
"terminal-kit": "^2.4.0"
|
"terminal-kit": "^2.4.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"discord-media-compressor-8mb": "index.js"
|
"DMC": "bin/index.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-identifier": {
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
|
@ -157,6 +158,11 @@
|
||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
@ -199,6 +205,19 @@
|
||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bluebird": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
@ -383,6 +402,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
|
},
|
||||||
"node_modules/console-control-strings": {
|
"node_modules/console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
|
@ -481,6 +505,11 @@
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/err-code": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
|
||||||
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||||
|
@ -546,6 +575,11 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||||
|
@ -574,6 +608,49 @@
|
||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-js": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=",
|
||||||
|
"dependencies": {
|
||||||
|
"bluebird": "^3.4.7",
|
||||||
|
"minimatch": "^3.0.3",
|
||||||
|
"proper-lockfile": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/file-js/node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/file-js/node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/filehound": {
|
||||||
|
"version": "1.17.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/filehound/-/filehound-1.17.6.tgz",
|
||||||
|
"integrity": "sha512-5q4zjFkI8W2zLmvbvyvI//K882IpEj6sMNXPUQlk5H6W4Wh3OSSylEAIEmMLELP9G7ileYjTKPXOn0YzzS55Lg==",
|
||||||
|
"dependencies": {
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
|
"file-js": "0.3.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"minimatch": "^5.0.0",
|
||||||
|
"moment": "^2.29.1",
|
||||||
|
"unit-compare": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
@ -869,6 +946,11 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
@ -911,6 +993,17 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
@ -921,6 +1014,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.29.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
|
||||||
|
"integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -1230,6 +1331,17 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proper-lockfile": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=",
|
||||||
|
"dependencies": {
|
||||||
|
"err-code": "^1.0.0",
|
||||||
|
"extend": "^3.0.0",
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"retry": "^0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pump": {
|
"node_modules/pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
|
@ -1315,6 +1427,14 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/retry": {
|
||||||
|
"version": "0.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
|
||||||
|
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reusify": {
|
"node_modules/reusify": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||||
|
@ -1633,6 +1753,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
||||||
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
||||||
},
|
},
|
||||||
|
"node_modules/unit-compare": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.14.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
@ -1917,6 +2045,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
|
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
|
||||||
},
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
|
},
|
||||||
"base64-js": {
|
"base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
@ -1944,6 +2077,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bluebird": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"braces": {
|
"braces": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
@ -2076,6 +2222,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
},
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
|
@ -2151,6 +2302,11 @@
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"err-code": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
|
||||||
|
},
|
||||||
"escalade": {
|
"escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||||
|
@ -2188,6 +2344,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
|
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
|
||||||
},
|
},
|
||||||
|
"extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
|
},
|
||||||
"fast-glob": {
|
"fast-glob": {
|
||||||
"version": "3.2.11",
|
"version": "3.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||||
|
@ -2213,6 +2374,48 @@
|
||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-js": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-js/-/file-js-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=",
|
||||||
|
"requires": {
|
||||||
|
"bluebird": "^3.4.7",
|
||||||
|
"minimatch": "^3.0.3",
|
||||||
|
"proper-lockfile": "^1.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filehound": {
|
||||||
|
"version": "1.17.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/filehound/-/filehound-1.17.6.tgz",
|
||||||
|
"integrity": "sha512-5q4zjFkI8W2zLmvbvyvI//K882IpEj6sMNXPUQlk5H6W4Wh3OSSylEAIEmMLELP9G7ileYjTKPXOn0YzzS55Lg==",
|
||||||
|
"requires": {
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
|
"file-js": "0.3.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"minimatch": "^5.0.0",
|
||||||
|
"moment": "^2.29.1",
|
||||||
|
"unit-compare": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
@ -2435,6 +2638,11 @@
|
||||||
"type-check": "~0.3.2"
|
"type-check": "~0.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
|
},
|
||||||
"lru-cache": {
|
"lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
@ -2462,6 +2670,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
||||||
},
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||||
|
@ -2472,6 +2688,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
|
||||||
|
"integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -2698,6 +2919,17 @@
|
||||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||||
},
|
},
|
||||||
|
"proper-lockfile": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=",
|
||||||
|
"requires": {
|
||||||
|
"err-code": "^1.0.0",
|
||||||
|
"extend": "^3.0.0",
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"retry": "^0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"pump": {
|
"pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
|
@ -2757,6 +2989,11 @@
|
||||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"retry": {
|
||||||
|
"version": "0.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
|
||||||
|
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
|
||||||
|
},
|
||||||
"reusify": {
|
"reusify": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||||
|
@ -2988,6 +3225,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
|
||||||
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
|
||||||
},
|
},
|
||||||
|
"unit-compare": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=",
|
||||||
|
"requires": {
|
||||||
|
"moment": "^2.14.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"universalify": {
|
"universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||||
|
|
11
package.json
11
package.json
|
@ -3,10 +3,14 @@
|
||||||
"version": "1.0.1",
|
"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",
|
"description": "helps free discord users to send any media(image, video, audio) and not get limited by discords 8mb file limit",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": "./index.js",
|
"bin": {
|
||||||
|
"DMC": "./bin/index.js"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.js",
|
"start": "node bin/index.js",
|
||||||
"build": "pkg -t --compress GZip package.json"
|
"build": "pkg .",
|
||||||
|
"test": "node fieldTest.cjs"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"discord",
|
"discord",
|
||||||
|
@ -18,6 +22,7 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cli-progress": "^3.11.0",
|
"cli-progress": "^3.11.0",
|
||||||
|
"filehound": "^1.17.6",
|
||||||
"pkg": "^5.6.0",
|
"pkg": "^5.6.0",
|
||||||
"require-runtime": "^2.0.0",
|
"require-runtime": "^2.0.0",
|
||||||
"terminal-kit": "^2.4.0"
|
"terminal-kit": "^2.4.0"
|
||||||
|
|
Loading…
Reference in a new issue