Discord-Media-Compressor-su.../index.js
2022-05-02 03:47:49 +02:00

96 lines
3.4 KiB
JavaScript

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')
//Create terminal readlines
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
//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])
}
else {
console.log("Unsupported format")
rl.question("press enter to exit...", () => { process.exit() })
process.exit()
}
//create progress bar
const bar1 = new cliProgress.SingleBar({
synchronousUpdate: true,
align: "left",
hideCursor: true
}, cliProgress.Presets.shades_classic)
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
const seconds = arr[0] * 3600 + arr[1] * 60 + (+arr[2]) // converting to s
return Number.parseFloat(seconds)
}
function ffprobe(file) {
return new Promise((resolve, reject) => {
exec(`ffprobe "${file}"`, (error, stdout, stderr) => {
resolve(stderr)
})
})
}
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() })
})
}