Univerter 3.0 !!!

This commit is contained in:
Bingus_Violet 2023-11-20 14:39:04 -06:00
parent 700a19bfd6
commit f9da622fbf
4 changed files with 262 additions and 201 deletions

227
index.js
View file

@ -2,32 +2,19 @@ const ytdl = require('ytdl-core'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
express = require('express'), express = require('express'),
ffmpeg = require('ffmpeg'), bodyParser = require('body-parser'),
bodyParser = require('body-parser') cp = require("child_process"),
ffmpeg = require('ffmpeg-static')
const PORT = process.env.PORT || 8080 const PORT = process.env.PORT || 8080
const app = express() const app = express()
if (fs.existsSync(path.join(__dirname, 'cached'))) {
fs.rmSync(path.join(__dirname, 'cached'), { recursive: true, force: true }) var formats = {
"matroska": "mkv"
} }
const characters = "abcdefghijklmnopqrstuvwxyz!@$%^*()[]_-=+" const characters = "abcdefghijklmnopqrstuvwxyz!@$%^*()[]_-=+ "
function formatBytes(bytes, decimals = 2) {
if (!+bytes) return '0 Bytes'
const k = 1024
const dm = decimals < 0 ? 0 : decimals
const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}
fs.mkdirSync(path.join(__dirname, 'cached'))
const cacheDuration = 30 || process.env.CACHEDUR
process.on('uncaughtException', (err, origin) => { process.on('uncaughtException', (err, origin) => {
fs.writeSync( fs.writeSync(
@ -39,11 +26,11 @@ process.on('uncaughtException', (err, origin) => {
app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.urlencoded({ extended: false }))
app.get("/getLink", async (req, res) => { app.get("/download", async (req, res) => {
const url = req.query.url const url = req.query.url
const format = req.query.format const format = req.query.format
const quality = req.query.quality const quality = req.query.quality
const redir = req.query.redirect const defin = req.query.definition
res.setHeader("X-Accel-Buffering", "no") res.setHeader("X-Accel-Buffering", "no")
@ -64,158 +51,68 @@ app.get("/getLink", async (req, res) => {
if ((characters + characters.toUpperCase()).includes(letter)) { if ((characters + characters.toUpperCase()).includes(letter)) {
filename += letter filename += letter
} }
} }
if (["mp4", "webm"].includes(format)) { if (format in ["mp3", "ogg", "wav"]) {
var ytvid = ytdl(url, { 'quality': quality, 'format': format, 'filter': 'videoandaudio' }) var audio = ytdl(url, { filter: 'audioonly', quality: quality })
var debounce = false audio.pipe(res)
ytvid.on("progress", (chunk, cd, td) => {
if (!debounce) { } else if (defin == "hd") {
res.setHeader('Content-Disposition', `attachment; filename="${filename}.${format}";`) var video = ytdl(url, { filter: 'videoonly', quality: quality })
res.setHeader('Content-Type', `video/${format}`) var audio = ytdl(url, { filter: 'audioonly', highWaterMark: 1<<25 })
console.log(`${filename}.${format}"`)
res.setHeader("Content-Length", td) const ffmpegProcess = cp.spawn(ffmpeg, [
ytvid.pipe(res) '-i', `pipe:3`,
debounce = true '-i', `pipe:4`,
} '-map','0:v',
'-map','1:a',
'-c:v', 'copy',
'-c:a', 'libmp3lame',
'-crf','27',
'-preset','veryfast',
'-movflags','frag_keyframe+empty_moov',
'-f', format,
'-loglevel','error',
'-'
], {
stdio: [
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
],
}) })
video.pipe(ffmpegProcess.stdio[3])
audio.pipe(ffmpegProcess.stdio[4])
res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`);
ffmpegProcess.stdio[1].pipe(res)
} else { } else {
if (redir != "redirect") { var video = ytdl(url, { filter: 'videoandaudio', quality: quality })
res.setHeader("Content-Type", "text/html");
res.write(`<link rel="stylesheet" href="/style.css">`) const ffmpegProcess = cp.spawn(ffmpeg, [
res.write(` '-i', `pipe:3`,
<style> '-c:v', 'copy',
p { '-c:a', 'libmp3lame',
display: block; '-crf','27',
} '-preset','veryfast',
</style> '-movflags','frag_keyframe+empty_moov',
`) '-f', format,
} '-loglevel','error',
'-'
], {
stdio: [
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
],
})
video.pipe(ffmpegProcess.stdio[3])
// String(Math.floor(Math.random() * 100000)) + res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`);
var ytpath = path.join(__dirname, 'cached/' + ytdl.getVideoID(url) + '.mp4') // res.setHeader('Content-Length', fs.readFileSync(dest).length)
if (redir != "redirect") { ffmpegProcess.stdio[1].pipe(res)
res.write(`<p>Starting download...</p>`)
}
var lastp = 0
if ("mp3 ogg wav".includes(format)) {
var ytvid = ytdl(url, { 'quality': quality, 'format': 'mp4', filter: "audioonly" })
} else {
var ytvid = ytdl(url, { 'quality': quality, 'format': 'mp4', filter: "videoandaudio" })
}
if (redir != "redirect") {
ytvid.on("progress", (data, ctotal, etotal) => {
var integer = 1
var percent = (Math.ceil(ctotal / etotal * 100))
if (percent % integer == 0 && lastp != percent) {
res.write(`<p class="percent" id="percent${percent}">Downloading... ${percent}% (${formatBytes(ctotal)})</p>`)
res.write(`
<style>
#percent${lastp} {
display: none;
}
</style>
`)
lastp = percent
}
})
}
ytvid.pipe(fs.createWriteStream(ytpath))
.on("close", () => {
if (redir != "redirect") {
res.write("<p>Downloaded!</p>")
}
var proc = new ffmpeg(ytpath)
// res.write(`<p>Converting... (May take a while, <a href="https://github.com/Violets-puragtory/NoJS-YTConverter"> doesn't support progress updates yet</a>)</p>`)
var endpath = ('cached/' + ytdl.getVideoID(url) + String(Math.floor(Math.random() * 10000000)) + "Converted." + format)
if (redir != "redirect") {
res.write(`<p>Starting Video Conversion... Conversion may be slow depending on instance.</p>`)
}
proc.then(function (video) {
video
.setVideoDuration(vidinfo.videoDetails.lengthSeconds)
.setVideoFormat(format)
.save(endpath, (error, file) => {
if (redir != "redirect") {
res.write(`<p>Converted! (<a href="https://github.com/damianociarla/node-ffmpeg/issues/33">Why doesn't conversion support %s?</a>)</p>`)
res.write(`
<style>
.cv {
display: none;
}
</style>
`)
res.write(`<p><a href="/download?path=${path.basename(file)}&filename=${filename}.${format}" target="_blank">Link to video download!</a> (Link is deleted after ${cacheDuration} minutes!)</p>`)
if (redir == "redirectjs") {
res.write(`
<script>
window.location = "/download?path=${path.basename(file)}&filename=${filename}.${format}"
</script>
`)
}
} else {
res.redirect(`/download?path=${path.basename(file)}&filename=${filename}.${format}`)
}
setTimeout(() => {
if (fs.existsSync(ytpath)) {
fs.unlinkSync(ytpath)
}
if (fs.existsSync(file)) {
fs.unlinkSync(file)
}
}, 60 * 1000)
})
})
var count = 0
async function update() {
if (fs.existsSync(endpath)) {
var ffile = await fs.readFileSync(endpath)
var yt = await fs.readFileSync(ytpath)
res.write(`<p class="cv" id="convert${count}">Converting... (${formatBytes(ffile.length)})</p>`)
res.write(`
<style>
#convert${count - 1} {
display: none;
}
</style>
`)
count += 1
// }
}
if ( redir != "redirect") {
setTimeout(() => {
update()
}, 2000);
}
}
update()
})
} }
});
app.get('/download', (req, res) => {
var file = req.query.path
var filename = req.query.filename
var dest = path.join(__dirname, 'cached/', file)
if (fs.existsSync(dest)) {
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
res.setHeader('Content-Length', fs.readFileSync(dest).length)
fs.createReadStream(dest).pipe(res)
} else {
res.header("Content-Type", "text/html")
res.write(`<link rel="stylesheet" href="/style.css">`)
res.write(`<p>Uh oh! It seems that video couldn't be found... Maybe the URL expired? Or, the link was invalid. <br>If you believe this was a mistake, please put a issue on <a href="https://github.com/Violets-puragtory/NoJS-YTConverter/">Github</a></p>`, () => {
res.end()
})
}
}) })
app.use(express.static(path.join(__dirname, 'static'))) app.use(express.static(path.join(__dirname, 'static')))

196
package-lock.json generated
View file

@ -1,20 +1,39 @@
{ {
"name": "youtubeconverter", "name": "youtubeconverter",
"version": "0.2.0", "version": "2.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "youtubeconverter", "name": "youtubeconverter",
"version": "1.2.0", "version": "2.1.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"express": "^4.18.2", "express": "^4.18.2",
"ffmpeg": "^0.0.4", "ffmpeg-static": "^5.2.0",
"ytdl-core": "^4.11.5" "ytdl-core": "^4.11.5"
} }
}, },
"node_modules/@derhuerst/http-basic": {
"version": "8.2.4",
"resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz",
"integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==",
"dependencies": {
"caseless": "^0.12.0",
"concat-stream": "^2.0.0",
"http-response-object": "^3.0.1",
"parse-cache-control": "^1.0.1"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
},
"node_modules/accepts": { "node_modules/accepts": {
"version": "1.3.8", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@ -27,6 +46,38 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/agent-base/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/agent-base/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/array-flatten": { "node_modules/array-flatten": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -55,6 +106,11 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -75,6 +131,25 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
"node_modules/concat-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
"engines": [
"node >= 6.0"
],
"dependencies": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.0.2",
"typedarray": "^0.0.6"
}
},
"node_modules/content-disposition": { "node_modules/content-disposition": {
"version": "0.5.4", "version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@ -145,6 +220,14 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"engines": {
"node": ">=6"
}
},
"node_modules/escape-html": { "node_modules/escape-html": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@ -236,12 +319,19 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/ffmpeg": { "node_modules/ffmpeg-static": {
"version": "0.0.4", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz", "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.2.0.tgz",
"integrity": "sha512-3TgWUJJlZGQn+crJFyhsO/oNeRRnGTy6GhgS98oUCIfZrOW5haPPV7DUfOm3xJcHr5q3TJpjk2GudPutrNisRA==", "integrity": "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==",
"hasInstallScript": true,
"dependencies": { "dependencies": {
"when": ">= 0.0.1" "@derhuerst/http-basic": "^8.2.0",
"env-paths": "^2.2.0",
"https-proxy-agent": "^5.0.0",
"progress": "^2.0.3"
},
"engines": {
"node": ">=16"
} }
}, },
"node_modules/finalhandler": { "node_modules/finalhandler": {
@ -332,6 +422,47 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/http-response-object": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
"dependencies": {
"@types/node": "^10.0.3"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/https-proxy-agent/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/https-proxy-agent/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/iconv-lite": { "node_modules/iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -459,6 +590,11 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/parse-cache-control": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
"integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="
},
"node_modules/parseurl": { "node_modules/parseurl": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -472,6 +608,14 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
}, },
"node_modules/progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/proxy-addr": { "node_modules/proxy-addr": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -520,6 +664,19 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -617,6 +774,14 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/toidentifier": { "node_modules/toidentifier": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@ -637,6 +802,11 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
"node_modules/unpipe": { "node_modules/unpipe": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -645,6 +815,11 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/utils-merge": { "node_modules/utils-merge": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@ -661,11 +836,6 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/when": {
"version": "3.7.8",
"resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz",
"integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw=="
},
"node_modules/ytdl-core": { "node_modules/ytdl-core": {
"version": "4.11.5", "version": "4.11.5",
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz", "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz",

View file

@ -1,6 +1,6 @@
{ {
"name": "youtubeconverter", "name": "univerter",
"version": "2.1.0", "version": "3.0.0",
"description": "A web youtube converter for converting videos to mp4, mp3, and other supported formats", "description": "A web youtube converter for converting videos to mp4, mp3, and other supported formats",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@ -25,7 +25,7 @@
"dependencies": { "dependencies": {
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"express": "^4.18.2", "express": "^4.18.2",
"ffmpeg": "^0.0.4", "ffmpeg-static": "^5.2.0",
"ytdl-core": "^4.11.5" "ytdl-core": "^4.11.5"
} }
} }

View file

@ -8,15 +8,15 @@
<link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/style.css">
<title>Youtube Downloader</title> <title>Univerter</title>
</head> </head>
<body> <body>
<h1>Youtube Downloader <p>v2.2</p> <h1>Univerter <p>v3.0</p>
<hr> <hr>
</h1> </h1>
<form action="/getLink" method="get" target="_blank"> <form action="/download" method="get" target="_blank">
<div class="setting"> <div class="setting">
<p style="margin-bottom: 1px;">Video URL:</p> <p style="margin-bottom: 1px;">Video URL:</p>
<input required id="url" placeholder="Enter url" name="url"> <input required id="url" placeholder="Enter url" name="url">
@ -24,24 +24,26 @@
<div class="setting"> <div class="setting">
<p>Quality:</p> <p>Quality:</p>
<br>
<select required id="quality" name="quality"> <select required id="quality" name="quality">
<option value="highest">Highest</option> <option value="highest">Highest</option>
<option value="lowest">Lowest</option> <option value="lowest">Lowest</option>
</select> </select>
<select required id="definition" name="definition">
<option value="sd">SD (Standard Definition)</option>
<option value="hd">HD (High Definition)</option>
</select>
</div> </div>
<!-- <div class="setting">
<p>Filename:</p>
<input required id="filename" placeholder="Enter filename" name="filename">
</div> -->
<div class="setting"> <div class="setting">
<p>Format:</p> <p>Format:</p>
<select required id="format" name="format"> <select required id="format" name="format">
<option disabled>Video Options</option> <option disabled>Video Options</option>
<option value="mp4" class="tooltip1">.mp4 (fastest)</option> <option value="mp4">.mp4</option>
<option value="webm" class="tooltip1">.webm (fastest)</option> <option value="matroska">.mkv</option>
<option value="flv">.flv</option> <option value="flv">.flv</option>
<option value="avi">.avi</option> <option value="avi">.avi</option>
<option value="mpeg">.mpeg</option>
<option value="mov">.mov</option> <option value="mov">.mov</option>
<option disabled>Audio Options</option> <option disabled>Audio Options</option>
<option value="mp3">.mp3</option> <option value="mp3">.mp3</option>
@ -49,21 +51,13 @@
<option value="wav">.wav</option> <option value="wav">.wav</option>
</select> </select>
</div> </div>
<!-- <p class="note">* When using mp4 and webm, progress updates and redirect options are disabled, as it is directly downloaded to the browser.</p> -->
<div class="setting">
<p>Redirect:</p>
<select required id="redirect" name="redirect">
<option value="redirectjs">Redirect (JS, reccomended)</option>
<option value="false">Don't auto redirect</option>
<option value="redirect">Redirect (Not reccomended)</option>
</select>
</div>
<br> <br>
<input type="submit"> <input type="submit">
</form> </form>
<br> <br>
<p>The SD option only supports 720p and below, HD supports all qualities. HD is experimental, so please report issues :D</p>
<p><a href="https://ko-fi.com/bingus_violet">Please consider donating</a> or host the website yourself! Anything <p><a href="https://ko-fi.com/bingus_violet">Please consider donating</a> or host the website yourself! Anything
helps! (Check <a href="https://github.com/Violets-puragtory/NoJS-YTConverter">github</a> for more info)</p> helps! (Check <a href="https://codeberg.org/Bingus_Violet/Univerter">Codeberg</a> for more info)</p>
</body> </body>
</html> </html>