diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 9a1f7f4..0000000 --- a/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -npm-debug.log -cached \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a74cdec..0000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -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" ] \ No newline at end of file diff --git a/README.md b/README.md index b808fcc..21b55b8 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,27 @@ # Univerter -A web downloader & converter for videos with no client-sided javascript. It can be found at https://univerter.dev +A web downloader for Youtube videos. It can be found at https://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. +Currently only supporting Youtube, and not many formats. For old Univerter, which supports a variety of sites, visit https://legacy.univerter.dev. # 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. Clone the repository - -```bash -git clone https://github.com/Violets-puragtory/YoutubeConverter -cd YoutubeConverter -``` - -2. Install Dependancies - +### 1. Install Dependancies +Always make sure your dependencies are up to date! Univerter's dependencies may change from time to time. - [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) -3. Download NodeJS Dependencies +### 2. Clone the repository + +```bash +git clone https://git.viois.gay/violet/Univerter +cd Univerter +``` + +### 3. Download NodeJS Dependencies ```bash npm install @@ -50,22 +35,10 @@ npm start # Environment Variables -`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.) +`PORT`= [Preffered Port] (Default is port 8080) # 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) \ No newline at end of file diff --git a/config.json b/config.json deleted file mode 100644 index c4a70a4..0000000 --- a/config.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "qualityOptions": [ - "2160", - "1140", - "1080", - "720", - "480", - "360", - "240", - "144" - ], - "formats": { - "video": [ - "mp4", - "mkv" - ], - "audio": [ - "mp3", - "wav" - ] - } -} \ No newline at end of file diff --git a/downloader.js b/downloader.js new file mode 100644 index 0000000..70a3f04 --- /dev/null +++ b/downloader.js @@ -0,0 +1,124 @@ +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!") + } +}) \ No newline at end of file diff --git a/express.js b/express.js new file mode 100644 index 0000000..4e7b12b --- /dev/null +++ b/express.js @@ -0,0 +1,18 @@ +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 +} \ No newline at end of file diff --git a/index.js b/index.js index e133cac..299fb4e 100644 --- a/index.js +++ b/index.js @@ -1,230 +1,2 @@ -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(`

` + data + `

`) - }) - - var debounce = false - - ytdlpProcess.stdout.setEncoding('utf-8') - ytdlpProcess.stdout.on('data', (data) => { - if (!debounce) { - if (data.includes("max-filesize")) { - debounce = true - res.write(`

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!)

`) - } - else if (data.includes("[download]")) { - res.write(``) - lastDownload += 1 - res.write(`

` + data.substring(12) + `

`) - } - } - - - }) - - 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(`"`) - res.write(downloadHTML.substring(downloadHTML.indexOf("{CONTENT}") + 9) + ``, () => { res.end() }) - } else { - res.write("

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.

") - } - }) - - 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) -}) \ No newline at end of file +require("./express.js") +require("./downloader.js") \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b64921b..6cbce1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "univerter", - "version": "3.2.0", + "version": "4.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "univerter", - "version": "3.2.0", + "version": "4.0.0", "license": "MIT", "dependencies": { + "@distube/ytdl-core": "^4.14.4", "child_process": "^1.0.2", "express": "^4.18.2", "ffmpeg-static": "^5.2.0" @@ -28,6 +29,26 @@ "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", @@ -388,6 +409,65 @@ "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", @@ -468,6 +548,19 @@ "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", @@ -519,6 +612,15 @@ "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", @@ -589,6 +691,21 @@ "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", @@ -603,6 +720,12 @@ "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", @@ -624,6 +747,12 @@ "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", @@ -648,6 +777,12 @@ "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", @@ -732,6 +867,21 @@ "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", @@ -749,6 +899,24 @@ "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", @@ -757,6 +925,16 @@ "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", @@ -791,6 +969,19 @@ "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", @@ -1072,6 +1263,37 @@ "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", @@ -1134,6 +1356,15 @@ "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", @@ -1167,6 +1398,11 @@ "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", @@ -1219,6 +1455,16 @@ "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", @@ -1227,6 +1473,11 @@ "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", @@ -1242,6 +1493,11 @@ "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", @@ -1252,6 +1508,11 @@ "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", @@ -1323,6 +1584,17 @@ "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", @@ -1337,11 +1609,30 @@ "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", diff --git a/package.json b/package.json index aa48d85..80b1f6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "univerter", - "version": "3.2.0", + "version": "4.0.0", "description": "A web youtube converter for converting videos to mp4, mp3, and other supported formats", "main": "index.js", "scripts": { @@ -23,6 +23,7 @@ }, "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" diff --git a/static/index.html b/static/index.html index 471a6d8..ef5c825 100644 --- a/static/index.html +++ b/static/index.html @@ -8,8 +8,12 @@ + + + + - + @@ -20,7 +24,7 @@

Univerter

-
+

Video URL:

@@ -34,7 +38,7 @@ - +
@@ -44,29 +48,26 @@ - - - +
+ +

Trim Silence (mp3)

+
+
+ +
-
-
+ -

- Powered by yt-dlp -
- Inspired by Cobalt
- Check out the beta! (It breaks much less!)
-

+

Inspired by Cobalt

+

Developed by Violet

diff --git a/static/js/jquery.js b/static/js/jquery.js new file mode 100644 index 0000000..35906b9 --- /dev/null +++ b/static/js/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},m=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||m).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/animatedSelector,-effects/Tween",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),b=new RegExp(ge+"|>"),A=new RegExp(g),D=new RegExp("^"+t+"$"),N={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+d),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},L=/^(?:input|select|textarea|button)$/i,j=/^h\d$/i,O=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,P=/[+~]/,H=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),q=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=K(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{E.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){E={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(V(e),e=e||C,T)){if(11!==d&&(u=O.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return E.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return E.call(n,a),n}else{if(u[2])return E.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return E.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||p&&p.test(t))){if(c=t,f=e,1===d&&(b.test(t)||m.test(t))){(f=P.test(t)&&X(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=k)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+G(l[o]);c=l.join(",")}try{return E.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function B(e){return e[k]=!0,e}function F(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function $(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return B(function(o){return o=+o,B(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function X(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=C&&9===n.nodeType&&n.documentElement&&(r=(C=n).documentElement,T=!ce.isXMLDoc(C),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=C&&(t=C.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=F(function(e){return r.appendChild(e).id=ce.expando,!C.getElementsByName||!C.getElementsByName(ce.expando).length}),le.disconnectedMatch=F(function(e){return i.call(e,"*")}),le.scope=F(function(){return C.querySelectorAll(":scope")}),le.cssHas=F(function(){try{return C.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(x.filter.ID=function(e){var t=e.replace(H,q);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(H,q);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&T){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},x.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&T)return t.getElementsByClassName(e)},p=[],F(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||p.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+k+"-]").length||p.push("~="),e.querySelectorAll("a#"+k+"+*").length||p.push(".#.+[+~]"),e.querySelectorAll(":checked").length||p.push(":checked"),(t=C.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&p.push(":enabled",":disabled"),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||p.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||p.push(":has"),p=p.length&&new RegExp(p.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===C||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),C}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),T&&!h[t+" "]&&(!p||!p.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(H,q),e[3]=(e[3]||e[4]||e[5]||"").replace(H,q),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return N.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&A.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(H,q).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||E,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:k.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:m,!0)),C.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=m.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,E=ce(m);var S=/^(?:parents|prev(?:Until|All))/,A={children:!0,contents:!0,next:!0,prev:!0};function D(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;re=m.createDocumentFragment().appendChild(m.createElement("div")),(be=m.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),re.appendChild(be),le.checkClone=re.cloneNode(!0).cloneNode(!0).lastChild.checked,re.innerHTML="",le.noCloneChecked=!!re.cloneNode(!0).lastChild.defaultValue,re.innerHTML="",le.option=!!re.lastChild;var Te={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Ee(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function ke(e,t){for(var n=0,r=e.length;n",""]);var Se=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ie(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function We(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n
",2===yt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=m.implementation.createHTMLDocument("")).createElement("base")).href=m.location.href,t.head.appendChild(r)):t=m),o=!n&&[],(i=C.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||K})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Qe(le.pixelPosition,function(e,t){if(t)return t=Ve(e,n),$e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 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")) + }) +}) \ No newline at end of file diff --git a/static/style.css b/static/style.css index 9fa715c..a05654c 100644 --- a/static/style.css +++ b/static/style.css @@ -76,6 +76,13 @@ body { align-items: center; } +@media screen and (min-height: 700px) { + html, + body { + height: 100%; + } +} + .mainDiv { width: 100%; /* outline: 2px white solid; */ @@ -86,13 +93,6 @@ 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); } -#adv { +input[type="checkbox"] { accent-color: var(--primary-color); - width: 1.15rem; - height: 1.15rem; + width: 1.05rem; + height: 1.05rem; } .error { diff --git a/yt-dlp b/yt-dlp deleted file mode 100755 index ef67b03..0000000 Binary files a/yt-dlp and /dev/null differ