From aeef6b351d922810ca2c9d72bd27a155604d5566 Mon Sep 17 00:00:00 2001 From: aandrew-me Date: Sat, 1 Jun 2024 16:13:13 +0300 Subject: [PATCH] Add proxy support --- assets/css/extra.css | 8 ++ html/preferences.html | 7 ++ package-lock.json | 4 +- package.json | 2 +- src/playlist.js | 233 ++++++++++++++++++++--------------- src/preferences.js | 11 ++ src/renderer.js | 180 ++++++++++++++++----------- src/translate_preferences.js | 1 + translations/en.json | 3 +- 9 files changed, 271 insertions(+), 178 deletions(-) diff --git a/assets/css/extra.css b/assets/css/extra.css index 8f09c58..e9a6fea 100644 --- a/assets/css/extra.css +++ b/assets/css/extra.css @@ -297,3 +297,11 @@ body::-webkit-scrollbar-thumb { background: linear-gradient(rgb(110, 110, 110), rgb(77, 77, 77)); border-radius: 8px; } + +#proxyTxt:valid { + border: 2px solid var(--greenBtn); +} + +#proxyTxt:invalid { + border: 2px solid var(--redBtn); +} diff --git a/html/preferences.html b/html/preferences.html index af66fde..a2d922a 100644 --- a/html/preferences.html +++ b/html/preferences.html @@ -128,6 +128,13 @@
+ +
+ Proxy + +
+
+
diff --git a/package-lock.json b/package-lock.json index 9688cf3..d88743e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ytdownloader", - "version": "3.17.0", + "version": "3.17.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ytdownloader", - "version": "3.17.0", + "version": "3.17.4", "license": "GPL-3.0", "dependencies": { "electron-updater": "^5.3.0", diff --git a/package.json b/package.json index c61b172..b837ab0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "yt-dlp-wrap-plus": "^2.3.18" }, "name": "ytdownloader", - "version": "3.17.4", + "version": "3.17.5", "main": "main.js", "scripts": { "start": "electron .", diff --git a/src/playlist.js b/src/playlist.js index 654f2b6..e4f8df9 100644 --- a/src/playlist.js +++ b/src/playlist.js @@ -69,6 +69,7 @@ let foldernameFormat = "%(playlist_title)s"; let filenameFormat = "%(playlist_index)s.%(title)s.%(ext)s"; let playlistIndex = 1; let playlistEnd = ""; +let proxy = "" /** * @@ -113,6 +114,9 @@ function download(type) { configArg = "--config-location"; configTxt = `"${localStorage.getItem("configPath")}"`; } + proxy = localStorage.getItem("proxy") || ""; + console.log("Proxy:", proxy) + nameFormatting(); originalCount = 0; @@ -174,12 +178,54 @@ function download(type) { const controller = new AbortController(); if (type === "video") { + const args = [ + format, + "--yes-playlist", + "-o", + `"${path.join(downloadDir, foldernameFormat, filenameFormat)}"`, + "-I", + `"${playlistIndex}:${playlistEnd}"`, + "--ffmpeg-location", + ffmpeg, + cookieArg, + browser, + configArg, + configTxt, + "--embed-metadata", + subs, + subLangs, + videoType == "mp4" ? "--embed-thumbnail" : "", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + `"${url}"`, + ].filter(item => item); + downloadProcess = ytdlp.exec( - [ - format, + args, + {shell: true, detached: false}, + controller.signal + ); + } else { + // Youtube provides m4a as audio, so no need to convert + if ( + (url.includes("youtube.com/") || url.includes("youtu.be/")) && + format === "m4a" && + audioQuality === "auto" + ) { + console.log("Downloading m4a without extracting") + + const args = [ "--yes-playlist", + "--no-warnings", + "-f", + `ba[ext=${format}]/ba`, "-o", - `"${path.join(downloadDir, foldernameFormat, filenameFormat)}"`, + `"${path.join( + downloadDir, + foldernameFormat, + filenameFormat + )}"`, "-I", `"${playlistIndex}:${playlistEnd}"`, "--ffmpeg-location", @@ -191,87 +237,62 @@ function download(type) { "--embed-metadata", subs, subLangs, - videoType == "mp4" ? "--embed-thumbnail" : "", + "--embed-thumbnail", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, `"${url}"`, - ], - {shell: true, detached: false}, - controller.signal - ); - } else { - // Youtube provides m4a as audio, so no need to convert - if ( - (url.includes("youtube.com/") || url.includes("youtu.be/")) && - format === "m4a" && - audioQuality === "auto" - ) { - console.log("Downloading m4a without extracting") + ].filter(item => item); + downloadProcess = ytdlp.exec( - [ - "--yes-playlist", - "--no-warnings", - "-f", - `ba[ext=${format}]/ba`, - "-o", - `"${path.join( - downloadDir, - foldernameFormat, - filenameFormat - )}"`, - "-I", - `"${playlistIndex}:${playlistEnd}"`, - "--ffmpeg-location", - ffmpeg, - cookieArg, - browser, - configArg, - configTxt, - "--embed-metadata", - subs, - subLangs, - "--embed-thumbnail", - `"${url}"`, - ], + args, {shell: true, detached: false}, controller.signal ); } else { console.log("Extracting audio") + + const args = [ + "--yes-playlist", + "--no-warnings", + "-x", + "--audio-format", + format, + "--audio-quality", + audioQuality, + "-o", + `"${path.join( + downloadDir, + foldernameFormat, + filenameFormat + )}"`, + "-I", + `"${playlistIndex}:${playlistEnd}"`, + "--ffmpeg-location", + ffmpeg, + cookieArg, + browser, + configArg, + configTxt, + "--embed-metadata", + subs, + subLangs, + format === "mp3" || format === "m4a" ? "--embed-thumbnail" : "", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + `"${url}"`, + ].filter(item => item); + downloadProcess = ytdlp.exec( - [ - "--yes-playlist", - "--no-warnings", - "-x", - "--audio-format", - format, - "--audio-quality", - audioQuality, - "-o", - `"${path.join( - downloadDir, - foldernameFormat, - filenameFormat - )}"`, - "-I", - `"${playlistIndex}:${playlistEnd}"`, - "--ffmpeg-location", - ffmpeg, - cookieArg, - browser, - configArg, - configTxt, - "--embed-metadata", - subs, - subLangs, - format === "mp3" || format === "m4a" ? "--embed-thumbnail" : "", - `"${url}"`, - ], + args, {shell: true, detached: false}, controller.signal ); } } - downloadProcess.on("ytDlpEvent", (eventType, eventData) => { + downloadProcess.on("ytDlpEvent", (_eventType, eventData) => { // console.log(eventData); if (eventData.includes(playlistTxt)) { @@ -409,23 +430,29 @@ function downloadThumbnails() { hideOptions(); nameFormatting(); managePlaylistRange(); + + const args = [ + "--yes-playlist", + "--no-warnings", + "-o", + `"${path.join(downloadDir, foldernameFormat, filenameFormat)}"`, + cookieArg, + browser, + "--write-thumbnail", + "--convert-thumbnails png", + "--skip-download", + "-I", + `"${playlistIndex}:${playlistEnd}"`, + "--ffmpeg-location", + ffmpeg, + proxy ? "--no-check-certificate" : "", + "--proxy", + proxy, + `"${url}"`, + ].filter(item => item); + const downloadProcess = ytdlp.exec( - [ - "--yes-playlist", - "--no-warnings", - "-o", - `"${path.join(downloadDir, foldernameFormat, filenameFormat)}"`, - cookieArg, - browser, - "--write-thumbnail", - "--convert-thumbnails png", - "--skip-download", - "-I", - `"${playlistIndex}:${playlistEnd}"`, - "--ffmpeg-location", - ffmpeg, - `"${url}"`, - ], + args, {shell: true, detached: false} ); @@ -479,21 +506,27 @@ function saveLinks() { hideOptions(); nameFormatting(); managePlaylistRange(); + + const args = [ + "--yes-playlist", + "--no-warnings", + cookieArg, + browser, + "--skip-download", + "--print-to-file", + "webpage_url", + `"${path.join(downloadDir, foldernameFormat, "links.txt")}"`, + "--skip-download", + "-I", + `"${playlistIndex}:${playlistEnd}"`, + proxy ? "--no-check-certificate" : "", + "--proxy", + proxy, + `"${url}"`, + ].filter(item => item); + const downloadProcess = ytdlp.exec( - [ - "--yes-playlist", - "--no-warnings", - cookieArg, - browser, - "--skip-download", - "--print-to-file", - "webpage_url", - `"${path.join(downloadDir, foldernameFormat, "links.txt")}"`, - "--skip-download", - "-I", - `"${playlistIndex}:${playlistEnd}"`, - `"${url}"`, - ], + args, {shell: true, detached: false} ); diff --git a/src/preferences.js b/src/preferences.js index ac55863..5fd453c 100644 --- a/src/preferences.js +++ b/src/preferences.js @@ -138,6 +138,17 @@ getId("preferredVideoCodec").addEventListener("change", () => { localStorage.setItem("preferredVideoCodec", preferredVideoCodec); }); +// Proxy +let proxy = localStorage.getItem("proxy"); +if (proxy) { + getId("proxyTxt").value = proxy; +} +getId("proxyTxt").addEventListener("change", () => { + proxy = getId("proxyTxt").value; + localStorage.setItem("proxy", proxy); +}); + + // Reload function reload() { ipcRenderer.send("reload"); diff --git a/src/renderer.js b/src/renderer.js index 5dd2d80..ff3f6c2 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -70,6 +70,7 @@ let maxActiveDownloads = 5; let showMoreFormats = false; let configArg = ""; let configTxt = ""; +let proxy = ""; if (localStorage.getItem("configPath")) { configArg = "--config-location"; @@ -319,6 +320,8 @@ async function getInfo(url) { showMoreFormats = false; } + proxy = getLocalStorageItem("proxy"); + // Whether to use browser cookies or not if (localStorage.getItem("browser")) { browser = localStorage.getItem("browser"); @@ -336,18 +339,23 @@ async function getInfo(url) { // Twitter/X compatibility url = url.replace("//x.com/", "//twitter.com/") + const infoOptions = [ + "-j", + "--no-playlist", + "--no-warnings", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + cookieArg, + browser, + configArg, + configTxt, + `"${url}"`, + ].filter(item => item) + const infoProcess = cp.spawn( `"${ytDlp}"`, - [ - "-j", - "--no-playlist", - "--no-warnings", - cookieArg, - browser, - configArg, - configTxt, - `"${url}"`, - ], + infoOptions, { shell: true, } @@ -1082,28 +1090,33 @@ function download( // If video has no sound, audio needs to be downloaded console.log("Downloading both video and audio"); + const args = [ + range1 || rangeOption, + range2 || rangeCmd, + "-f", + `${format_id}${audioFormat}`, + "-o", + `"${path.join(downloadDir, filename + `.${ext}`)}"`, + "--ffmpeg-location", + ffmpeg, + subs1 || subs, + subs2 || subLangs, + "--no-playlist", + "--embed-metadata", + ext == "mp4" && audioForVideoExt === "m4a" ? "--embed-thumbnail" : "", + configArg, + configTxt, + cookieArg, + browser, + "--no-mtime", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + `"${url}"`, + ].filter(item => item); + downloadProcess = ytdlp.exec( - [ - range1 || rangeOption, - range2 || rangeCmd, - "-f", - `${format_id}${audioFormat}`, - "-o", - `"${path.join(downloadDir, filename + `.${ext}`)}"`, - "--ffmpeg-location", - ffmpeg, - subs1 || subs, - subs2 || subLangs, - "--no-playlist", - "--embed-metadata", - ext == "mp4" && audioForVideoExt === "m4a" ? "--embed-thumbnail" : "", - configArg, - configTxt, - cookieArg, - browser, - "--no-mtime", - `"${url}"`, - ], + args, {shell: true, detached: false}, controller.signal ); @@ -1121,29 +1134,34 @@ function download( console.log(extractFormat1); console.log(extractQuality1); + const args = [ + "-x", + "--audio-format", + extractFormat1, + "--audio-quality", + extractQuality1, + "-o", + `"${path.join(downloadDir, filename + `.${extractExt}`)}"`, + "--ffmpeg-location", + ffmpeg, + "--no-playlist", + "--embed-metadata", + extractFormat1 == "m4a" || extractFormat1 == "mp3" + ? "--embed-thumbnail" + : "", + cookieArg, + browser, + configArg, + configTxt, + "--no-mtime", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + `"${url}"`, + ].filter(item => item) + downloadProcess = ytdlp.exec( - [ - "-x", - "--audio-format", - extractFormat1, - "--audio-quality", - extractQuality1, - "-o", - `"${path.join(downloadDir, filename + `.${extractExt}`)}"`, - "--ffmpeg-location", - ffmpeg, - "--no-playlist", - "--embed-metadata", - extractFormat1 == "m4a" || extractFormat1 == "mp3" - ? "--embed-thumbnail" - : "", - cookieArg, - browser, - configArg, - configTxt, - "--no-mtime", - `"${url}"`, - ], + args, {shell: true, detached: false}, controller.signal ); @@ -1152,28 +1170,33 @@ function download( else { console.log("downloading only audio or video with audio"); + const args = [ + range1 || rangeOption, + range2 || rangeCmd, + "-f", + format_id, + "-o", + `"${path.join(downloadDir, filename + `.${ext}`)}"`, + "--ffmpeg-location", + ffmpeg, + subs1 || subs, + subs2 || subLangs, + "--no-playlist", + "--embed-metadata", + ext == "m4a" || ext == "mp4" ? "--embed-thumbnail" : "", + cookieArg, + browser, + configArg, + configTxt, + "--no-mtime", + proxy ? "--no-check-certificate" : "", + proxy ? "--proxy" : "", + proxy, + `"${url}"`, + ].filter(item => item) + downloadProcess = ytdlp.exec( - [ - range1 || rangeOption, - range2 || rangeCmd, - "-f", - format_id, - "-o", - `"${path.join(downloadDir, filename + `.${ext}`)}"`, - "--ffmpeg-location", - ffmpeg, - subs1 || subs, - subs2 || subLangs, - "--no-playlist", - "--embed-metadata", - ext == "m4a" || ext == "mp4" ? "--embed-thumbnail" : "", - cookieArg, - browser, - configArg, - configTxt, - "--no-mtime", - `"${url}"`, - ], + args, {shell: true, detached: false}, controller.signal ); @@ -1344,6 +1367,15 @@ function showPopup(text) { }, 2200); } +/** + * + * @param {string} item + * @returns string + */ +function getLocalStorageItem(item) { + return localStorage.getItem(item) || ""; +} + // Menu getId("preferenceWin").addEventListener("click", () => { closeMenu(); diff --git a/src/translate_preferences.js b/src/translate_preferences.js index 6e8baa9..ca2d777 100644 --- a/src/translate_preferences.js +++ b/src/translate_preferences.js @@ -39,6 +39,7 @@ getId("trayTxt").textContent = i18n.__("Close app to system tray"); getId("autoUpdateTxt").textContent = i18n.__("Disable auto updates"); getId("showMoreFormatsTxt").textContent = i18n.__("Show more format options"); getId("preferredVideoCodecTxt").textContent = i18n.__("Preferred video codec"); +getId("proxyTitle").textContent = i18n.__("Proxy"); if (process.env.FLATPAK_ID) { getId("flatpakTxt").textContent = i18n.__( diff --git a/translations/en.json b/translations/en.json index d707f5a..dadfc2e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -110,5 +110,6 @@ "Preferred video codec": "Preferred video codec", "Show more format options": "Show more format options", "You need to give the app permission to access home directory to use this. You can do it with Flatseal by enabling the permission with text 'filesystem=home'": "You need to give the app permission to access home directory to use this. You can do it with Flatseal by enabling the permission with text 'filesystem=home'", - "No Audio":"No Audio" + "No Audio":"No Audio", + "Proxy": "Proxy" }