Changes to encoding, UI fixes

This commit is contained in:
Djkato 2022-05-29 01:58:41 +02:00
parent de08788b4f
commit f9bf73f6d7
5 changed files with 80 additions and 155 deletions

View file

@ -28,3 +28,6 @@ How to install(Windows, Linux, MacOS):
>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
For an amazing read on how to optimize vp9 for file sizes I reccomend this read: https://codeberg.org/deterenkelt/Nadeshiko/wiki/Researches%E2%80%89%E2%80%93%E2%80%89VP9-and-overshooting

View file

@ -67,10 +67,11 @@ async function main(menu = false) {
await checkFF()
const ui = new UI(settings.settings, settings.currentSetting, settings.settingsFile, filePaths?.length)
if (menu) savesettings = await ui.startMenu()
//file checks
let isListEncodable = true
if (menu) { savesettings = await ui.startMenu(); isListEncodable = false }
//check if all files exist
for (let i = 0; i < filePaths.length; i++) {
if (!fs.existsSync(filePaths[i])) {

View file

@ -1,4 +1,5 @@
const { exec } = require('child_process')
const termkit = require('terminal-kit')
class Encoder {
currentSetting
@ -50,9 +51,9 @@ class Encoder {
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)
//Calculates video bitrate to fit right under 8mb 2:6 audio:video. 8Mb * 8 = 64000 - 1000 for overhead, *0.97 to leave space for container.
const audioBitRate = Math.round((63000 / 8 * 2 / duration) * 0.97)
const videoBitRate = Math.round((63000 / 8 * 6 / duration) * 0.97)
//if command had argument of anotehr quality setting change to use that setting
if (this.encodePresetIndexArg) {
@ -60,8 +61,9 @@ class Encoder {
}
let command = ""
let crfIndex = 0
let isTwoPass = true
/* REMOVING CRF AS ITS NO LONGER USED -- REPLACE WITH -qmin equivalent
//Compares current video height to CRFMAP to determine optimal CRF
while (resolutionHeight > this.currentSetting.crfMap[crfIndex].resolution) {
crfIndex++
@ -71,29 +73,58 @@ class Encoder {
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?.bitrateError) {
command += `-b:v ${Math.round(videoBitRate / 100 * this.currentSetting.bitrateError)}k `
command += `-minrate ${Math.round(videoBitRate)}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
*/
//realtime doesnt support two pass, so just use real time settings
if (this.currentSetting.deadline == "realtime") {
command += `ffmpeg -y -i "${path}" -vcodec libvpx-vp9 -acodec libopus `
command += `-deadline ${this.currentSetting.deadline} `
command += `-quality ${this.currentSetting.deadline} `
command += `-cpu-used ${this.currentSetting.cpuUsed} `
command += `-undershoot-pct 0 -overshoot-pct 0 `
command += `-b:v ${Math.round(videoBitRate / 100 * this.currentSetting.bitrateError)}k `
command += `-minrate ${Math.round(videoBitRate * 0.5)}k `
command += `-maxrate ${Math.floor(videoBitRate * 1.4)}k `
command += `-b:a ${audioBitRate}k `
command += `-tile-columns 2 -threads 6 `
command += `-qmax 60`
command += `-g 240 `
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, false]
}
//Pass 1 force to have good deadline and cpu-used 1
command += `ffmpeg -y -i "${path}" -vcodec libvpx-vp9 -acodec libopus `
command += `-deadline good `
command += `-quality good `
command += `-cpu-used 1 `
command += `-undershoot-pct 0 -overshoot-pct 0 `
command += `-b:v ${Math.round(videoBitRate / 100 * this.currentSetting.bitrateError)}k `
command += `-minrate ${Math.round(videoBitRate * 0.5)}k `
command += `-maxrate ${Math.floor(videoBitRate * 1.2)}k `
command += `-b:a ${audioBitRate}k `
command += `-auto-alt-ref 6 `
command += `-qmax 60`
command += `-g 240 `
command += `-row-mt 1 -pass 1 -f webm NUL && `
//Pass 2 take in settings
command += `ffmpeg -y -i "${path}" -vcodec libvpx-vp9 -acodec libopus `
command += `-deadline ${this.currentSetting.deadline} `
command += `-quality ${this.currentSetting.deadline} `
command += `-cpu-used ${this.currentSetting.cpuUsed} `
command += `-undershoot-pct 0 -overshoot-pct 0 `
command += `-b:v ${Math.round(videoBitRate / 100 * this.currentSetting.bitrateError)}k `
command += `-minrate ${Math.round(videoBitRate * 0.5)}k `
command += `-maxrate ${Math.floor(videoBitRate * 1.4)}k `
command += `-b:a ${audioBitRate}k `
command += `-tile-columns 2 -threads 6 `
command += `-auto-alt-ref 6 `
command += `-qmax 60`
command += `-g 240 `
command += `-row-mt 1 -pass 2 "${out}.webm" `
return [command, duration, isTwoPass]
}

View file

@ -35,142 +35,32 @@ class SettingsManager {
async #makeNewSettingsFile() {
const settings = `
{
"currentSetting": 3,
"currentSetting": 2,
"presets": [{
"name": "Most efficient 8 megabytes of your life",
"cpuUsed": 0,
"deadline": "best",
"bitrateError": 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
}]
"deadline": "good",
"bitrateError": 95
}, {
"name": "I have some time to kill",
"cpuUsed": 1,
"deadline": "good",
"bitrateError": 90,
"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
}]
"bitrateError": 95
}, {
"name": "Mid",
"cpuUsed": 3,
"deadline": "good",
"bitrateError": 80,
"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
}]
"deadline": "realtime",
"bitrateError": 90
}, {
"name": "I don't like waiting",
"cpuUsed": 4,
"deadline": 100,
"bitrateError": 70,
"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
}]
"cpuUsed": 5,
"deadline": "realtime",
"bitrateError": 80
}, {
"name": "I want it, NOW!",
"cpuUsed": 3,
"cpuUsed": 6,
"deadline": "realtime",
"bitrateError": 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
}]
"bitrateError": 70
}]
}
`

View file

@ -13,7 +13,7 @@ class UI {
this.term = termkit.terminal
this.multibar = new cliProgress.MultiBar({
format: '[{bar}] {percentage}% | output: "{filename}" | ETA: {eta_formatted}s | {duration_formatted} | {value}s/{total}s ',
format: '[{bar}] {percentage}% | output: "{filename}" | ETA: {eta_formatted} | Elapsed: {duration_formatted} | {value}s/{total}s ',
align: "left",
hideCursor: true,
autopadding: true,
@ -100,17 +100,17 @@ class UI {
async startMenu() {
await this.#menu()
}
async #menu(settingsFile) {
async #menu() {
let menu = []
for (let i = 0; i < this.settings.presets.length; i++) {
menu.push(`${i}. ${this.settings.presets[i].name}`)
}
this.term("How to convert: 8mb [optional: -preset {Index}] [filename.extension(s)]\n")
this.term("examples: \n")
this.term.italic(" 8mb -preset 0 file.mp3 file4.mov img.jpg\n")
this.term.italic(" 8mb.exe file34.wav file2.mp3\n\n")
this.term.grey("How to convert: 8mb [optional: -preset {Index}] [filename.extension(s)]\n")
this.term.grey("examples: \n")
this.term.italic.grey(" 8mb -preset 0 file.mp3 file4.mov img.jpg\n")
this.term.italic.grey(" 8mb 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(`"${this.settings.presets[this.settings.currentSetting].name}"`).yellow(" preset")
this.term.yellow("Currently using ").bgMagenta(`"${this.settings.presets[this.settings.currentSetting].name}"`).yellow(" preset\n")
this.term.singleColumnMenu(menu, (error, response) => {
this.settings.currentSetting = response.selectedIndex
this.term.green("\n Using").green.bold(` ${this.settings.presets[this.settings.currentSetting].name} `).green("setting\n")