Compare commits
No commits in common. "6fb90e6815e36bbe2b24797bd2035c6fca8cbea4" and "4ddd6fd98a54ef8871dfad12b14d5f217ffecf9c" have entirely different histories.
6fb90e6815
...
4ddd6fd98a
15 changed files with 341 additions and 508 deletions
3
.dockerignore
Normal file
3
.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
npm-debug.log
|
||||
cached
|
16
Dockerfile
Normal file
16
Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
|||
FROM node:20
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt install python3 pip ffmpeg -y \
|
||||
&& python3 -m pip install -U yt-dlp --break-system-packages
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD [ "node", "index.js" ]
|
53
README.md
53
README.md
|
@ -1,27 +1,42 @@
|
|||
# Univerter
|
||||
|
||||
A web downloader for Youtube videos. It can be found at https://univerter.dev
|
||||
A web downloader & converter for videos with no client-sided javascript. It can be found at https://univerter.dev
|
||||
|
||||
Currently only supporting Youtube, and not many formats. For old Univerter, which supports a variety of sites, visit https://legacy.univerter.dev.
|
||||
Currently supports a wide variety of formats and sites, but if you have any other formats you want supported, please open an issue.
|
||||
Formats added to Univerter must be supported by FFmpeg
|
||||
Support for sites will only be added if those sites are supported by yt-dlp.
|
||||
|
||||
# Installation
|
||||
|
||||
There are 2 main ways to install Univerter:
|
||||
|
||||
## Docker
|
||||
|
||||
The docker image can be found at https://hub.docker.com/r/bingusviolet/univerter
|
||||
Port 8080 (or whatever you set the environment variable to) is exposed inside the container. It can be exposed with `-p`
|
||||
Example:
|
||||
```bash
|
||||
docker run -p 8080:8080 bingusviolet/univerter
|
||||
```
|
||||
This will allow it to be found on port 8080 (E.G. `localhost:8080`)
|
||||
|
||||
## Node
|
||||
|
||||
### 1. Install Dependancies
|
||||
Always make sure your dependencies are up to date! Univerter's dependencies may change from time to time.
|
||||
1. Clone the repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Violets-puragtory/YoutubeConverter
|
||||
cd YoutubeConverter
|
||||
```
|
||||
|
||||
2. Install Dependancies
|
||||
|
||||
- [ffmpeg](https://github.com/FFmpeg/FFmpeg)
|
||||
- [node](https://github.com/nodejs/node)
|
||||
- [npm](https://github.com/npm/cli)
|
||||
- [yt-dlp](https://github.com/yt-dlp/yt-dlp)
|
||||
|
||||
### 2. Clone the repository
|
||||
|
||||
```bash
|
||||
git clone https://git.viois.gay/violet/Univerter
|
||||
cd Univerter
|
||||
```
|
||||
|
||||
### 3. Download NodeJS Dependencies
|
||||
3. Download NodeJS Dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
|
@ -35,10 +50,22 @@ npm start
|
|||
|
||||
# Environment Variables
|
||||
|
||||
`PORT`= [Preffered Port] (Default is port 8080)
|
||||
`PORT`= [Preffered Port] (8080 if unspecified)
|
||||
`MAX_FILESIZE` = [Max file size in MB] (Only applies to 1080p>, don't rely on this feature yet though, as it is unfinished.)
|
||||
|
||||
# To-Do
|
||||
- [ ] Save settings (per session)
|
||||
- [ ] Proper config
|
||||
- [ ] Advanced options menu
|
||||
- [ ] Add option for subtitles to file
|
||||
- [ ] Video Searching
|
||||
- [ ] Video Caching Options
|
||||
- [ ] Properly cleanup unnessacary files
|
||||
- [ ] Option to disable 1080p+
|
||||
- [ ] Option to disable Conversion
|
||||
|
||||
# Instances
|
||||
Here is a list of all currently public instances. If you want to add your instance to this list, please make an issue or pull request!
|
||||
|
||||
- https://univerter.dev (official)
|
||||
- https://yt.violets-purgatory.dev (official)
|
22
config.json
Normal file
22
config.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"qualityOptions": [
|
||||
"2160",
|
||||
"1140",
|
||||
"1080",
|
||||
"720",
|
||||
"480",
|
||||
"360",
|
||||
"240",
|
||||
"144"
|
||||
],
|
||||
"formats": {
|
||||
"video": [
|
||||
"mp4",
|
||||
"mkv"
|
||||
],
|
||||
"audio": [
|
||||
"mp3",
|
||||
"wav"
|
||||
]
|
||||
}
|
||||
}
|
124
downloader.js
124
downloader.js
|
@ -1,124 +0,0 @@
|
|||
const expressManager = require("./express.js"),
|
||||
path = require("path"),
|
||||
fs = require("fs"),
|
||||
ytdl = require("@distube/ytdl-core"),
|
||||
ffmpeg = require("ffmpeg-static"),
|
||||
cp = require("child_process")
|
||||
|
||||
var qualityLabels = [
|
||||
"144",
|
||||
"240",
|
||||
"360",
|
||||
"480",
|
||||
"720",
|
||||
"1080",
|
||||
"1440",
|
||||
"2160"
|
||||
]
|
||||
|
||||
var audioFormats = [
|
||||
"mp3"
|
||||
]
|
||||
|
||||
expressManager.app.get("/download", async (req, res) => {
|
||||
var url = req.query.url,
|
||||
quality = req.query.quality,
|
||||
format = req.query.format,
|
||||
trimAudio = req.query.trimAudio && audioFormats.includes(format) || false
|
||||
|
||||
if (ytdl.validateURL(url) && qualityLabels.includes(quality)) {
|
||||
var needsVideo = !audioFormats.includes(format)
|
||||
|
||||
var info = await ytdl.getInfo(url)
|
||||
|
||||
res.setHeader("Content-Disposition", `attachment; filename="${info.videoDetails.title.replace(/[^a-z0-9 ]/gi, '')}.${format}"`)
|
||||
|
||||
var audioFormat = ytdl.chooseFormat(info.formats, { filter: (format) => {
|
||||
return format.hasAudio && !format.hasVideo
|
||||
} })
|
||||
|
||||
var videoFormat = undefined
|
||||
|
||||
var qualityLabel = quality
|
||||
while (videoFormat == undefined) {
|
||||
for (let i = 0; i < info.formats.length; i++) {
|
||||
const format = info.formats[i];
|
||||
if (format.hasVideo && !format.hasAudio && format.height && format.height.toString() == qualityLabel.toString() && (format.videoCodec.includes("avc1") || format.codecs.includes("avc1"))) {
|
||||
// console.log(format.videoCodec)
|
||||
videoFormat = format
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (qualityLabels.indexOf(qualityLabel) - 1 < 0) {
|
||||
break
|
||||
}
|
||||
qualityLabel = qualityLabels[qualityLabels.indexOf(qualityLabel) - 1]
|
||||
}
|
||||
|
||||
if (!videoFormat) {
|
||||
videoFormat = ytdl.chooseFormat(info.formats, { filter: "videoonly" })
|
||||
}
|
||||
|
||||
var baseArgs = [
|
||||
// Remove ffmpeg's console spamming
|
||||
'-loglevel', 'error',
|
||||
// // Set inputs
|
||||
// '-i', 'pipe:4',
|
||||
// '-i', 'pipe:5',
|
||||
// Map audio & video from streams
|
||||
// '-map', '0:a',
|
||||
// '-map', '1:v',
|
||||
// Keep encoding
|
||||
'-c:v', 'copy',
|
||||
'-movflags','frag_keyframe+empty_moov',
|
||||
'-f', format,
|
||||
// Define output file
|
||||
'-',
|
||||
]
|
||||
|
||||
var inputArgs = [
|
||||
'-i', 'pipe:4'
|
||||
]
|
||||
|
||||
var mapArgs = [
|
||||
'-map', '0:a'
|
||||
]
|
||||
|
||||
var bonusArgs = []
|
||||
|
||||
if (needsVideo) {
|
||||
inputArgs = inputArgs.concat(['-i', 'pipe:5'])
|
||||
mapArgs = mapArgs.concat(['-map', '1:v'])
|
||||
}
|
||||
|
||||
if (trimAudio) {
|
||||
bonusArgs = bonusArgs.concat(['-af', 'silenceremove=1:0:-50dB'])
|
||||
}
|
||||
|
||||
var args = inputArgs.concat(mapArgs).concat(bonusArgs).concat(baseArgs)
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, args, {
|
||||
windowsHide: true,
|
||||
stdio: [
|
||||
/* Standard: stdin, stdout, stderr */
|
||||
'pipe', 'pipe', 'pipe',
|
||||
/* Custom: pipe:3, pipe:4, pipe:5 */
|
||||
'pipe', 'pipe', 'pipe',
|
||||
],
|
||||
});
|
||||
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
|
||||
var audio = ytdl(url, { format: audioFormat || "audioonly" })
|
||||
audio.pipe(ffmpegProcess.stdio[4])
|
||||
|
||||
if (needsVideo) {
|
||||
var video = ytdl(url, { format: videoFormat || "videoonly" })
|
||||
video.pipe(ffmpegProcess.stdio[5])
|
||||
}
|
||||
|
||||
} else {
|
||||
res.send("Invalid URL!")
|
||||
}
|
||||
})
|
18
express.js
18
express.js
|
@ -1,18 +0,0 @@
|
|||
const express = require("express"),
|
||||
path = require("path")
|
||||
|
||||
const PORT = process.env.PORT || 8080
|
||||
|
||||
var staticPath = path.join(__dirname, "static")
|
||||
|
||||
var app = express()
|
||||
|
||||
app.use(express.static(staticPath))
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log("Univerter now listening on PORT: " + PORT)
|
||||
})
|
||||
|
||||
module.exports = {
|
||||
app
|
||||
}
|
232
index.js
232
index.js
|
@ -1,2 +1,230 @@
|
|||
require("./express.js")
|
||||
require("./downloader.js")
|
||||
const fs = require('fs'),
|
||||
path = require('path'),
|
||||
express = require('express'),
|
||||
cp = require("child_process"),
|
||||
ffmpeg = require("ffmpeg-static")
|
||||
|
||||
const PORT = process.env.PORT || 8080
|
||||
const app = express()
|
||||
|
||||
const MAX_FILESIZE = process.env.MAX_FILESIZE || 500
|
||||
|
||||
var formats = {
|
||||
"mkv": "matroska"
|
||||
}
|
||||
|
||||
var fastFormats = ["mp4", "mkv", "mp3", "wav"]
|
||||
|
||||
app.get("/convert", async (req, res) => {
|
||||
var file = req.query.file || ""
|
||||
var format = req.query.format
|
||||
var url = req.query.url
|
||||
|
||||
var filePath = path.join(__dirname, 'downloads', file)
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
var ytdlpProcess = cp.spawnSync('./yt-dlp', ['--get-filename', url])
|
||||
var name = ytdlpProcess.stdout.toString()
|
||||
name = name.substring(0, name.lastIndexOf("[") - 1)
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(name)}.${format}"`);
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, [
|
||||
'-i', filePath,
|
||||
'-f', formats[format] || format,
|
||||
'-movflags', 'frag_keyframe+empty_moov',
|
||||
'-preset','ultrafast',
|
||||
'-crf', '23',
|
||||
'-loglevel', 'error',
|
||||
'-'
|
||||
], {
|
||||
stdio: [
|
||||
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
|
||||
],
|
||||
})
|
||||
|
||||
ffmpegProcess.stderr.setEncoding('utf-8')
|
||||
// ffmpegProcess.stderr.on('data', (data) => {
|
||||
// console.log(data)
|
||||
// })
|
||||
// These are debugging lines to watch FFMPEG output :3
|
||||
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
.on('close', () => {
|
||||
fs.rmSync(filePath)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
app.get("/download", async (req, res) => {
|
||||
const url = req.query.url
|
||||
const format = req.query.format || 'mp4'
|
||||
const quality = req.query.quality || '720'
|
||||
|
||||
res.setHeader("X-Accel-Buffering", "no")
|
||||
|
||||
var fileName = Math.ceil(Math.random() * 100_000_000_000).toString()
|
||||
var videoName = cp.spawnSync('./yt-dlp', ['-S', 'res:' + quality, '--get-filename', url]).stdout.toString()
|
||||
|
||||
videoName = videoName.substring(0, videoName.lastIndexOf('.'))
|
||||
videoName = videoName.substring(0, videoName.lastIndexOf('[') - 1)
|
||||
|
||||
if (!["mp3", "wav", "ogx"].includes(format) && Number(quality) > 720) {
|
||||
res.setHeader("Content-Type", "text/html")
|
||||
|
||||
var downloadHTML = fs.readFileSync(path.join(__dirname, 'resources/downloading.html')).toString()
|
||||
|
||||
res.write(downloadHTML.substring(0, downloadHTML.indexOf("{CONTENT}")))
|
||||
|
||||
var filePath = path.join(__dirname, 'downloads', fileName)
|
||||
var ytdlpProcess = cp.spawn('./yt-dlp', [
|
||||
url,
|
||||
'-o', filePath,
|
||||
'--max-filesize', MAX_FILESIZE + 'm',
|
||||
'-S', 'res:' + quality,
|
||||
'--no-playlist',
|
||||
])
|
||||
|
||||
var lastDownload = 0
|
||||
|
||||
ytdlpProcess.stderr.setEncoding('utf-8')
|
||||
ytdlpProcess.stderr.on('data', (data) => {
|
||||
// console.log(data)
|
||||
res.write(`<div class="error"><p>` + data + `</p></div>`)
|
||||
})
|
||||
|
||||
var debounce = false
|
||||
|
||||
ytdlpProcess.stdout.setEncoding('utf-8')
|
||||
ytdlpProcess.stdout.on('data', (data) => {
|
||||
if (!debounce) {
|
||||
if (data.includes("max-filesize")) {
|
||||
debounce = true
|
||||
res.write(`<p>Uh oh! The video you're trying to download is too large for this server's current settings ${MAX_FILESIZE}. Please try another server? (Visit main page and go to the codeberg for a list of instances!)</p>`)
|
||||
}
|
||||
else if (data.includes("[download]")) {
|
||||
res.write(`<style>#downloading${lastDownload}{ display: none; }</style>`)
|
||||
lastDownload += 1
|
||||
res.write(`<p id="downloading${lastDownload}">` + data.substring(12) + `</p>`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
var exited = false
|
||||
|
||||
ytdlpProcess.on('close', () => {
|
||||
|
||||
var files = fs.readdirSync(path.join(__dirname, 'downloads'))
|
||||
for (let index = 0; index < files.length; index++) {
|
||||
const file = files[index];
|
||||
if (file.includes(fileName)) {
|
||||
fileName = file
|
||||
filePath = path.join(__dirname, 'downloads', fileName)
|
||||
}
|
||||
}
|
||||
|
||||
if (exited) {
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.rmSync(filePath)
|
||||
}
|
||||
}
|
||||
else if (fs.existsSync(filePath)) {
|
||||
res.write(`<iframe src="/convert?file=${fileName}&format=${format}&url=${url}"></iframe>"`)
|
||||
res.write(downloadHTML.substring(downloadHTML.indexOf("{CONTENT}") + 9) + `<meta http-equiv="Refresh" content="0; url='/'" />`, () => { res.end() })
|
||||
} else {
|
||||
res.write("<p>An error has occured!!! We're not exactly sure what the error is, but we cant seem to find the download file. Double check the URL, and if the URL is fine, then file an issue on codeberg. </p>")
|
||||
}
|
||||
})
|
||||
|
||||
res.on("error", () => {
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.rmSync(filePath)
|
||||
}
|
||||
exited = true
|
||||
})
|
||||
} else if (["mp3", "wav", "opus"].includes(format)) {
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(videoName)}.${format}"`);
|
||||
|
||||
var ytdlpProcess = cp.spawn('./yt-dlp', [
|
||||
url,
|
||||
'-x',
|
||||
'-o', '-',
|
||||
'--max-filesize', MAX_FILESIZE + 'm',
|
||||
'--audio-format', 'mp3',
|
||||
'--no-playlist',
|
||||
])
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, [
|
||||
'-i', 'pipe:3',
|
||||
'-f', formats[format] || format,
|
||||
'-movflags', 'frag_keyframe+empty_moov',
|
||||
'-preset','ultrafast',
|
||||
'-crf', '23',
|
||||
'-loglevel', 'error',
|
||||
'-'
|
||||
], {
|
||||
stdio: [
|
||||
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
|
||||
],
|
||||
})
|
||||
|
||||
ytdlpProcess.stdout.pipe(ffmpegProcess.stdio[3])
|
||||
|
||||
ytdlpProcess.stderr.setEncoding('utf-8')
|
||||
// ytdlpProcess.stderr.on('data', (data) => {
|
||||
// console.log(data)
|
||||
// })
|
||||
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
} else {
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(videoName)}.${format}"`);
|
||||
|
||||
var ytdlpProcess = cp.spawn('./yt-dlp', [
|
||||
url,
|
||||
'-o', '-',
|
||||
'--max-filesize', MAX_FILESIZE + 'm',
|
||||
'-S', 'res:' + quality,
|
||||
'--no-playlist',
|
||||
])
|
||||
|
||||
const ffmpegProcess = cp.spawn(ffmpeg, [
|
||||
'-i', 'pipe:3',
|
||||
'-f', formats[format] || format,
|
||||
'-movflags', 'frag_keyframe+empty_moov',
|
||||
'-c:a', 'libmp3lame',
|
||||
'-preset','ultrafast',
|
||||
'-crf', '23',
|
||||
'-loglevel', 'error',
|
||||
'-'
|
||||
], {
|
||||
stdio: [
|
||||
'pipe', 'pipe', 'pipe', 'pipe', 'pipe',
|
||||
],
|
||||
})
|
||||
|
||||
ytdlpProcess.stdout.pipe(ffmpegProcess.stdio[3])
|
||||
|
||||
ytdlpProcess.stderr.setEncoding('utf-8')
|
||||
// ytdlpProcess.stderr.on('data', (data) => {
|
||||
// console.log(data)
|
||||
// })
|
||||
|
||||
ffmpegProcess.stdio[1].pipe(res)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
process.on('uncaughtException', (err, origin) => {
|
||||
fs.writeSync(
|
||||
process.stderr.fd,
|
||||
`Caught exception: ${err}\n` +
|
||||
`Exception origin: ${origin}`,
|
||||
);
|
||||
});
|
||||
|
||||
app.use(express.static(path.join(__dirname, 'static')))
|
||||
|
||||
app.listen(PORT, function () {
|
||||
console.log("Hosted on port " + PORT)
|
||||
})
|
295
package-lock.json
generated
295
package-lock.json
generated
|
@ -1,15 +1,14 @@
|
|||
{
|
||||
"name": "univerter",
|
||||
"version": "4.0.0",
|
||||
"version": "3.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "univerter",
|
||||
"version": "4.0.0",
|
||||
"version": "3.2.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@distube/ytdl-core": "^4.14.4",
|
||||
"child_process": "^1.0.2",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg-static": "^5.2.0"
|
||||
|
@ -29,26 +28,6 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@distube/ytdl-core": {
|
||||
"version": "4.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@distube/ytdl-core/-/ytdl-core-4.14.4.tgz",
|
||||
"integrity": "sha512-dHb4GW3qATIjRsS6VIhm3Pop7FdUcDFhsnyQlsPeXW7UhTPuNS0BmraKiTpFbpp0Ky+rxBQjJBfPRFsM+dT1fg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"http-cookie-agent": "^6.0.5",
|
||||
"m3u8stream": "^0.8.6",
|
||||
"miniget": "^4.2.3",
|
||||
"sax": "^1.4.1",
|
||||
"tough-cookie": "^4.1.4",
|
||||
"undici": "five"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/distubejs/ytdl-core?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "10.17.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
|
||||
|
@ -409,65 +388,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/http-cookie-agent": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-6.0.5.tgz",
|
||||
"integrity": "sha512-sfZ8fDgDP3B1YB+teqSnAK1aPgBu8reUUGxSsndP2XnYN6cM29EURXWXZqQQiaRdor3B4QjpkUNfv21syaO4DA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/3846masa"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tough-cookie": "^4.0.0",
|
||||
"undici": "^5.11.0 || ^6.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"undici": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/http-cookie-agent/node_modules/agent-base": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/http-cookie-agent/node_modules/debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/http-cookie-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==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
|
@ -548,19 +468,6 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/m3u8stream": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz",
|
||||
"integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"miniget": "^4.2.2",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -612,15 +519,6 @@
|
|||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/miniget": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz",
|
||||
"integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
|
@ -691,21 +589,6 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
|
@ -720,12 +603,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
|
@ -747,12 +624,6 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -777,12 +648,6 @@
|
|||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
|
@ -867,21 +732,6 @@
|
|||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
|
||||
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
|
@ -899,24 +749,6 @@
|
|||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.19.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.4.tgz",
|
||||
"integrity": "sha512-i3uaEUwNdkRq2qtTRRJb13moW5HWqviu7Vl7oYRYz++uPtGHJj+x7TGjcEuwS5Mt2P4nA0U9dhIX3DdB6JGY0g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
@ -925,16 +757,6 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
@ -969,19 +791,6 @@
|
|||
"parse-cache-control": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@distube/ytdl-core": {
|
||||
"version": "4.14.4",
|
||||
"resolved": "https://registry.npmjs.org/@distube/ytdl-core/-/ytdl-core-4.14.4.tgz",
|
||||
"integrity": "sha512-dHb4GW3qATIjRsS6VIhm3Pop7FdUcDFhsnyQlsPeXW7UhTPuNS0BmraKiTpFbpp0Ky+rxBQjJBfPRFsM+dT1fg==",
|
||||
"requires": {
|
||||
"http-cookie-agent": "^6.0.5",
|
||||
"m3u8stream": "^0.8.6",
|
||||
"miniget": "^4.2.3",
|
||||
"sax": "^1.4.1",
|
||||
"tough-cookie": "^4.1.4",
|
||||
"undici": "five"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.17.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
|
||||
|
@ -1263,37 +1072,6 @@
|
|||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"http-cookie-agent": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-6.0.5.tgz",
|
||||
"integrity": "sha512-sfZ8fDgDP3B1YB+teqSnAK1aPgBu8reUUGxSsndP2XnYN6cM29EURXWXZqQQiaRdor3B4QjpkUNfv21syaO4DA==",
|
||||
"requires": {
|
||||
"agent-base": "^7.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
|
||||
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
|
||||
"requires": {
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
|
@ -1356,15 +1134,6 @@
|
|||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"m3u8stream": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz",
|
||||
"integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==",
|
||||
"requires": {
|
||||
"miniget": "^4.2.2",
|
||||
"sax": "^1.2.4"
|
||||
}
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -1398,11 +1167,6 @@
|
|||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"miniget": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz",
|
||||
"integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
|
@ -1455,16 +1219,6 @@
|
|||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
|
@ -1473,11 +1227,6 @@
|
|||
"side-channel": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
|
@ -1493,11 +1242,6 @@
|
|||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -1508,11 +1252,6 @@
|
|||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
|
@ -1584,17 +1323,6 @@
|
|||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
|
||||
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
|
||||
"requires": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
}
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
|
@ -1609,30 +1337,11 @@
|
|||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
|
||||
},
|
||||
"undici": {
|
||||
"version": "6.19.4",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.19.4.tgz",
|
||||
"integrity": "sha512-i3uaEUwNdkRq2qtTRRJb13moW5HWqviu7Vl7oYRYz++uPtGHJj+x7TGjcEuwS5Mt2P4nA0U9dhIX3DdB6JGY0g=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "univerter",
|
||||
"version": "4.0.0",
|
||||
"version": "3.2.0",
|
||||
"description": "A web youtube converter for converting videos to mp4, mp3, and other supported formats",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -23,7 +23,6 @@
|
|||
},
|
||||
"homepage": "https://github.com/Violets-puragtory/YoutubeConverter#readme",
|
||||
"dependencies": {
|
||||
"@distube/ytdl-core": "^4.14.4",
|
||||
"child_process": "^1.0.2",
|
||||
"express": "^4.18.2",
|
||||
"ffmpeg-static": "^5.2.0"
|
||||
|
|
|
@ -8,12 +8,8 @@
|
|||
|
||||
<link rel="stylesheet" href="./style.css">
|
||||
|
||||
<script src="./js/jquery.js"></script>
|
||||
<script src="./js/js-cookie.js"></script>
|
||||
<script src="./js/main.js"></script>
|
||||
|
||||
<meta content="Univerter" property="og:title" />
|
||||
<meta content="Univerter is an extremely fast web downloader for Youtube videos." property="og:description" />
|
||||
<meta content="Univerter is a web video downloader & converter for Youtube, TikTok, Twitter, and more." property="og:description" />
|
||||
<meta content="https://univerter.dev/Images/Univerter%20Logo.png" property="og:image" />
|
||||
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
|
||||
|
||||
|
@ -24,7 +20,7 @@
|
|||
<div class="mainDiv">
|
||||
<h1>Univerter<hr></h1>
|
||||
|
||||
<form action="/download" method="get" target="_blank">
|
||||
<form action="/download" method="get">
|
||||
<p style="margin-bottom: 1px;">Video URL:</p>
|
||||
<input required type="url" id="url" placeholder="Enter URL" name="url">
|
||||
|
||||
|
@ -38,7 +34,7 @@
|
|||
<option value="480">480p</option>
|
||||
<option value="720" selected>720p</option>
|
||||
<option value="1080">1080p</option>
|
||||
<option value="1440">1440p (2k)</option>
|
||||
<option value="1440">1440p</option>
|
||||
<option value="2160">2160p (4k)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -48,26 +44,29 @@
|
|||
<select required id="format" name="format">
|
||||
<option disabled>Video Formats</option>
|
||||
<option value="mp4">.mp4</option>
|
||||
<option value="mkv">.mkv</option>
|
||||
<option disabled>Audio Formats</option>
|
||||
<option value="mp3" selected>.mp3</option>
|
||||
<option value="wav">.wav</option>
|
||||
<option value="opus">.ogx</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div id="audioOnly">
|
||||
<input style="display: inline-block" type="checkbox" id="trim" name="trimAudio">
|
||||
<p style="display: inline-block" for="trim">Trim Silence (mp3)</p>
|
||||
</div>
|
||||
<div id="videoAndAudio">
|
||||
<!-- <input style="display: inline-block" type="checkbox" id="trim" checked>
|
||||
<p style="display: inline-block" for="trim">Trim BALLS (mp4 only)</p> -->
|
||||
</div>
|
||||
<!-- <br> -->
|
||||
<!-- <input style="display: inline-block" type="checkbox" id="adv"> -->
|
||||
<!-- <p style="display: inline-block" for="adv">Enable Advanced options? (Beta)</p> -->
|
||||
|
||||
<br>
|
||||
<input type="submit">
|
||||
</form>
|
||||
<!-- <br> -->
|
||||
<br>
|
||||
|
||||
<p>Inspired by <a href="https://cobalt.tools">Cobalt</a></p>
|
||||
<p>Developed by <a href="https://violets-purgatory.dev">Violet</a></p>
|
||||
<p>
|
||||
Powered by <a target="_blank" href="https://github.com/yt-dlp/yt-dlp/">yt-dlp</a>
|
||||
<br>
|
||||
Inspired by <a href="https://cobalt.tools">Cobalt</a><br>
|
||||
Check out the <a href="https://beta.univerter.dev">beta!</a> (It breaks much less!)<br>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
|
2
static/js/jquery.js
vendored
2
static/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,2 +0,0 @@
|
|||
/*! js-cookie v3.0.5 | MIT */
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self,function(){var n=e.Cookies,o=e.Cookies=t();o.noConflict=function(){return e.Cookies=n,o}}())}(this,(function(){"use strict";function e(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)e[o]=n[o]}return e}var t=function t(n,o){function r(t,r,i){if("undefined"!=typeof document){"number"==typeof(i=e({},o,i)).expires&&(i.expires=new Date(Date.now()+864e5*i.expires)),i.expires&&(i.expires=i.expires.toUTCString()),t=encodeURIComponent(t).replace(/%(2[346B]|5E|60|7C)/g,decodeURIComponent).replace(/[()]/g,escape);var c="";for(var u in i)i[u]&&(c+="; "+u,!0!==i[u]&&(c+="="+i[u].split(";")[0]));return document.cookie=t+"="+n.write(r,t)+c}}return Object.create({set:r,get:function(e){if("undefined"!=typeof document&&(!arguments.length||e)){for(var t=document.cookie?document.cookie.split("; "):[],o={},r=0;r<t.length;r++){var i=t[r].split("="),c=i.slice(1).join("=");try{var u=decodeURIComponent(i[0]);if(o[u]=n.read(c,u),e===u)break}catch(e){}}return e?o[e]:o}},remove:function(t,n){r(t,"",e({},n,{expires:-1}))},withAttributes:function(n){return t(this.converter,e({},this.attributes,n))},withConverter:function(n){return t(e({},this.converter,n),this.attributes)}},{attributes:{value:Object.freeze(o)},converter:{value:Object.freeze(n)}})}({read:function(e){return'"'===e[0]&&(e=e.slice(1,-1)),e.replace(/(%[\dA-F]{2})+/gi,decodeURIComponent)},write:function(e){return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,decodeURIComponent)}},{path:"/"});return t}));
|
|
@ -1,24 +0,0 @@
|
|||
var audioFormats = ["mp3"]
|
||||
|
||||
function updateOptions() {
|
||||
var format = $("#format").val()
|
||||
if (audioFormats.includes(format)) {
|
||||
$("#audioOnly > input").attr("disabled", false)
|
||||
$("#videoAndAudio > input").attr("disabled", true)
|
||||
} else {
|
||||
$("#audioOnly > input").attr("disabled", true)
|
||||
$("#videoAndAudio > input").attr("disabled", false)
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
updateOptions()
|
||||
$("#format").on("change", updateOptions)
|
||||
|
||||
$("#quality").val(Cookies.get("quality") || "720")
|
||||
$("#trim").prop("checked", Cookies.get("trim") == "true" || false)
|
||||
$("form").submit(() => {
|
||||
Cookies.set("quality", $("#quality").val())
|
||||
Cookies.set("trim", $("#trim").prop("checked"))
|
||||
})
|
||||
})
|
|
@ -76,13 +76,6 @@ body {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
@media screen and (min-height: 700px) {
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.mainDiv {
|
||||
width: 100%;
|
||||
/* outline: 2px white solid; */
|
||||
|
@ -93,6 +86,13 @@ iframe {
|
|||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-height: 500px) {
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
select,
|
||||
input {
|
||||
font-size: 1.3rem;
|
||||
|
@ -131,10 +131,10 @@ option {
|
|||
background-color: rgba(0, 0, 20);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
#adv {
|
||||
accent-color: var(--primary-color);
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
width: 1.15rem;
|
||||
height: 1.15rem;
|
||||
}
|
||||
|
||||
.error {
|
||||
|
|
BIN
yt-dlp
Executable file
BIN
yt-dlp
Executable file
Binary file not shown.
Loading…
Reference in a new issue