Univerter 3.0 !!!
This commit is contained in:
parent
700a19bfd6
commit
f9da622fbf
4 changed files with 262 additions and 201 deletions
225
index.js
225
index.js
|
@ -2,33 +2,20 @@ const ytdl = require('ytdl-core'),
|
|||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
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 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!@$%^*()[]_-=+ "
|
||||
|
||||
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) => {
|
||||
fs.writeSync(
|
||||
process.stderr.fd,
|
||||
|
@ -39,11 +26,11 @@ process.on('uncaughtException', (err, origin) => {
|
|||
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
|
||||
app.get("/getLink", async (req, res) => {
|
||||
app.get("/download", async (req, res) => {
|
||||
const url = req.query.url
|
||||
const format = req.query.format
|
||||
const quality = req.query.quality
|
||||
const redir = req.query.redirect
|
||||
const defin = req.query.definition
|
||||
|
||||
res.setHeader("X-Accel-Buffering", "no")
|
||||
|
||||
|
@ -64,158 +51,68 @@ app.get("/getLink", async (req, res) => {
|
|||
if ((characters + characters.toUpperCase()).includes(letter)) {
|
||||
filename += letter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (["mp4", "webm"].includes(format)) {
|
||||
var ytvid = ytdl(url, { 'quality': quality, 'format': format, 'filter': 'videoandaudio' })
|
||||
var debounce = false
|
||||
ytvid.on("progress", (chunk, cd, td) => {
|
||||
if (!debounce) {
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}.${format}";`)
|
||||
res.setHeader('Content-Type', `video/${format}`)
|
||||
console.log(`${filename}.${format}"`)
|
||||
res.setHeader("Content-Length", td)
|
||||
ytvid.pipe(res)
|
||||
debounce = true
|
||||
}
|
||||
if (format in ["mp3", "ogg", "wav"]) {
|
||||
var audio = ytdl(url, { filter: 'audioonly', quality: quality })
|
||||
audio.pipe(res)
|
||||
|
||||
} else if (defin == "hd") {
|
||||
var video = ytdl(url, { filter: 'videoonly', quality: quality })
|
||||
var audio = ytdl(url, { filter: 'audioonly', highWaterMark: 1<<25 })
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, [
|
||||
'-i', `pipe:3`,
|
||||
'-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 {
|
||||
if (redir != "redirect") {
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
var video = ytdl(url, { filter: 'videoandaudio', quality: quality })
|
||||
|
||||
res.write(`<link rel="stylesheet" href="/style.css">`)
|
||||
res.write(`
|
||||
<style>
|
||||
p {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`)
|
||||
}
|
||||
|
||||
|
||||
// String(Math.floor(Math.random() * 100000)) +
|
||||
var ytpath = path.join(__dirname, 'cached/' + ytdl.getVideoID(url) + '.mp4')
|
||||
|
||||
if (redir != "redirect") {
|
||||
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)
|
||||
})
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, [
|
||||
'-i', `pipe:3`,
|
||||
'-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',
|
||||
],
|
||||
})
|
||||
|
||||
var count = 0
|
||||
video.pipe(ffmpegProcess.stdio[3])
|
||||
|
||||
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()
|
||||
})
|
||||
}
|
||||
});
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`);
|
||||
// res.setHeader('Content-Length', fs.readFileSync(dest).length)
|
||||
|
||||
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()
|
||||
})
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'static')))
|
||||
|
|
196
package-lock.json
generated
196
package-lock.json
generated
|
@ -1,20 +1,39 @@
|
|||
{
|
||||
"name": "youtubeconverter",
|
||||
"version": "0.2.0",
|
||||
"version": "2.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "youtubeconverter",
|
||||
"version": "1.2.0",
|
||||
"version": "2.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.20.2",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg": "^0.0.4",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"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": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
|
@ -27,6 +46,38 @@
|
|||
"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": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
|
@ -55,6 +106,11 @@
|
|||
"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": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
|
@ -75,6 +131,25 @@
|
|||
"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": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
|
@ -145,6 +220,14 @@
|
|||
"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": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
|
@ -236,12 +319,19 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/ffmpeg": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz",
|
||||
"integrity": "sha512-3TgWUJJlZGQn+crJFyhsO/oNeRRnGTy6GhgS98oUCIfZrOW5haPPV7DUfOm3xJcHr5q3TJpjk2GudPutrNisRA==",
|
||||
"node_modules/ffmpeg-static": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.2.0.tgz",
|
||||
"integrity": "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA==",
|
||||
"hasInstallScript": true,
|
||||
"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": {
|
||||
|
@ -332,6 +422,47 @@
|
|||
"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": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
@ -459,6 +590,11 @@
|
|||
"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": {
|
||||
"version": "1.3.3",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -520,6 +664,19 @@
|
|||
"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": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -617,6 +774,14 @@
|
|||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
@ -637,6 +802,11 @@
|
|||
"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": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
@ -645,6 +815,11 @@
|
|||
"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": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
|
@ -661,11 +836,6 @@
|
|||
"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": {
|
||||
"version": "4.11.5",
|
||||
"resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-4.11.5.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "youtubeconverter",
|
||||
"version": "2.1.0",
|
||||
"name": "univerter",
|
||||
"version": "3.0.0",
|
||||
"description": "A web youtube converter for converting videos to mp4, mp3, and other supported formats",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -25,7 +25,7 @@
|
|||
"dependencies": {
|
||||
"body-parser": "^1.20.2",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg": "^0.0.4",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"ytdl-core": "^4.11.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
|
||||
<title>Youtube Downloader</title>
|
||||
<title>Univerter</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Youtube Downloader <p>v2.2</p>
|
||||
<h1>Univerter <p>v3.0</p>
|
||||
<hr>
|
||||
</h1>
|
||||
|
||||
<form action="/getLink" method="get" target="_blank">
|
||||
<form action="/download" method="get" target="_blank">
|
||||
<div class="setting">
|
||||
<p style="margin-bottom: 1px;">Video URL:</p>
|
||||
<input required id="url" placeholder="Enter url" name="url">
|
||||
|
@ -24,24 +24,26 @@
|
|||
|
||||
<div class="setting">
|
||||
<p>Quality:</p>
|
||||
<br>
|
||||
<select required id="quality" name="quality">
|
||||
<option value="highest">Highest</option>
|
||||
<option value="lowest">Lowest</option>
|
||||
</select>
|
||||
|
||||
<select required id="definition" name="definition">
|
||||
<option value="sd">SD (Standard Definition)</option>
|
||||
<option value="hd">HD (High Definition)</option>
|
||||
</select>
|
||||
</div>
|
||||
<!-- <div class="setting">
|
||||
<p>Filename:</p>
|
||||
<input required id="filename" placeholder="Enter filename" name="filename">
|
||||
</div> -->
|
||||
|
||||
<div class="setting">
|
||||
<p>Format:</p>
|
||||
<select required id="format" name="format">
|
||||
<option disabled>Video Options</option>
|
||||
<option value="mp4" class="tooltip1">.mp4 (fastest)</option>
|
||||
<option value="webm" class="tooltip1">.webm (fastest)</option>
|
||||
<option value="mp4">.mp4</option>
|
||||
<option value="matroska">.mkv</option>
|
||||
<option value="flv">.flv</option>
|
||||
<option value="avi">.avi</option>
|
||||
<option value="mpeg">.mpeg</option>
|
||||
<option value="mov">.mov</option>
|
||||
<option disabled>Audio Options</option>
|
||||
<option value="mp3">.mp3</option>
|
||||
|
@ -49,21 +51,13 @@
|
|||
<option value="wav">.wav</option>
|
||||
</select>
|
||||
</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>
|
||||
<input type="submit">
|
||||
</form>
|
||||
<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
|
||||
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>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue