diff --git a/index.js b/index.js
index 9714372..8ce5bf7 100644
--- a/index.js
+++ b/index.js
@@ -2,32 +2,19 @@ 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
+const characters = "abcdefghijklmnopqrstuvwxyz!@$%^*()[]_-=+ "
process.on('uncaughtException', (err, origin) => {
fs.writeSync(
@@ -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(` `)
- res.write(`
-
- `)
- }
+ 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',
+ ],
+ })
+ video.pipe(ffmpegProcess.stdio[3])
- // String(Math.floor(Math.random() * 100000)) +
- var ytpath = path.join(__dirname, 'cached/' + ytdl.getVideoID(url) + '.mp4')
+ res.setHeader('Content-Disposition', `attachment; filename="${filename}.${formats[format] || format}"`);
+ // res.setHeader('Content-Length', fs.readFileSync(dest).length)
- if (redir != "redirect") {
- res.write(`
Starting download...
`)
- }
- 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(`Downloading... ${percent}% (${formatBytes(ctotal)})
`)
- res.write(`
-
- `)
- lastp = percent
- }
- })
- }
- ytvid.pipe(fs.createWriteStream(ytpath))
- .on("close", () => {
- if (redir != "redirect") {
- res.write("Downloaded!
")
- }
- var proc = new ffmpeg(ytpath)
- // res.write(`Converting... (May take a while, doesn't support progress updates yet )
`)
- var endpath = ('cached/' + ytdl.getVideoID(url) + String(Math.floor(Math.random() * 10000000)) + "Converted." + format)
- if (redir != "redirect") {
- res.write(`Starting Video Conversion... Conversion may be slow depending on instance.
`)
- }
- proc.then(function (video) {
- video
- .setVideoDuration(vidinfo.videoDetails.lengthSeconds)
- .setVideoFormat(format)
- .save(endpath, (error, file) => {
- if (redir != "redirect") {
- res.write(`Converted! (Why doesn't conversion support %s? )
`)
- res.write(`
-
- `)
- res.write(`Link to video download! (Link is deleted after ${cacheDuration} minutes!)
`)
- if (redir == "redirectjs") {
- res.write(`
-
- `)
- }
- } 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(`Converting... (${formatBytes(ffile.length)})
`)
- res.write(`
-
- `)
- count += 1
- // }
- }
- if ( redir != "redirect") {
- setTimeout(() => {
- update()
- }, 2000);
- }
- }
- update()
- })
+ ffmpegProcess.stdio[1].pipe(res)
}
-});
-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(` `)
- res.write(`Uh oh! It seems that video couldn't be found... Maybe the URL expired? Or, the link was invalid. If you believe this was a mistake, please put a issue on Github
`, () => {
- res.end()
- })
- }
})
app.use(express.static(path.join(__dirname, 'static')))
diff --git a/package-lock.json b/package-lock.json
index 07e6c4f..509c96a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index b8d907e..037ca3c 100644
--- a/package.json
+++ b/package.json
@@ -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"
}
}
diff --git a/static/index.html b/static/index.html
index 0e64264..22b991a 100644
--- a/static/index.html
+++ b/static/index.html
@@ -8,15 +8,15 @@
- Youtube Downloader
+ Univerter
- Youtube Downloader v2.2
+ Univerter v3.0
-