diff --git a/.gitignore b/.gitignore index 5799f75..1eea57b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ # Build data. -pornhub_dl/pornhub_dl.spec -PornHub Downloader.spec -pornhub_dl/build -Build/Release +Build/Windows/Release +pornhub-dl.spec # Visual Studio project files. PornHub Downloader.pyproj @@ -13,8 +11,8 @@ PornHub Downloader.sln Downloads.ytdl Downloads -# Python cache. -__pycache__ - # Advertisement animation file. -Advertisement.gif \ No newline at end of file +Advertisement.gif + +# Python cache. +__pycache__ \ No newline at end of file diff --git a/Qt/Build/build.bat b/Build/Windows/build.bat similarity index 50% rename from Qt/Build/build.bat rename to Build/Windows/build.bat index f47b2c6..7b0e18a 100644 --- a/Qt/Build/build.bat +++ b/Build/Windows/build.bat @@ -1,14 +1,15 @@ :: Переход в директорию проекта. -cd ..\ +cd ..\..\ :: Сборка приложения. -pyinstaller --distpath %~dp0\Release --i icon.ico --version-file Build\metadata.txt --onefile main.py +pyinstaller --distpath %~dp0\Release --i icon.ico --version-file Build\Windows\metadata.txt --onefile main.py --name pornhub-dl :: Копирование в директорию сборки необходимых компонентов приложения. -xcopy /Y /I yt-dlp Build\Release\yt-dlp -xcopy /Y Advertisement.gif Build\Release -xcopy /Y Settings.json Build\Release -xcopy /Y icon.ico Build\Release +xcopy /Y /I Source\GUI\Qt\Locales.json Build\Windows\Release\Source\GUI\Qt\ +xcopy /Y /I yt-dlp Build\Windows\Release\yt-dlp +xcopy /Y Advertisement.gif Build\Windows\Release +xcopy /Y icon.ico Build\Windows\Release +xcopy /Y Settings.json Build\Windows\Release :: Удаление файлов сборки приложения. -rmdir /q /s Build\main \ No newline at end of file +rmdir /q /s Build\pornhub-dl \ No newline at end of file diff --git a/Qt/Build/metadata.txt b/Build/Windows/metadata.txt similarity index 100% rename from Qt/Build/metadata.txt rename to Build/Windows/metadata.txt diff --git a/Qt/Source/Locale.py b/Qt/Source/Locale.py deleted file mode 100644 index a7438e8..0000000 --- a/Qt/Source/Locale.py +++ /dev/null @@ -1,104 +0,0 @@ -import ctypes -import locale -import sys - -# Словарь локализаций. -LOCALES = { - "DE": [ - "Werbung", - "Klar", - "Copy output", - "Ausgabe kopieren", - "Fügen sie hier links zu videos ein", - "Ausgabeprotokolle", - "Links einfügen", - "Einstellung", - "Qualität", - "Auflösung des heruntergeladenen videos.", - "Thema", - "Stil des programmfensters.", - "Sortieren nach modellen" - ], - "EN": [ - "Advertisement", - "Clear", - "Copy output", - "Download", - "Paste here links to videos", - "Output logs", - "Paste links", - "Settings", - "Cuality", - "Resolution of the downloaded video.", - "Theme", - "Style of the program window.", - "Sort by models" - ], - "PL": [ - "Reklama", - "Oczyścić", - "Kopiuj dzienniki", - "Pozbyć się", - "Wstaw tutaj linki do filmów", - "Logi", - "Wstaw linki", - "Konfiguracja", - "Jakość", - "Rozdzielczość pobieranego wideo.", - "Temat", - "Styl okna programu.", - "Sortuj według modeli" - ], - "RU": [ - "Реклама", - "Очистить", - "Копировать логи", - "Скачать", - "Вставьте сюда ссылки на видео", - "Логи", - "Вставить ссылки", - "Настройки", - "Качество", - "Разрешение загружаемого видео.", - "Тема", - "Стиль окна программы.", - "По моделям" - ], - "UK": [ - "Реклама", - "Очистити", - "Копіювати логи", - "Скачати", - "Вставте сюди посилання на відео", - "Логи", - "Вставити посилання", - "Налаштування", - "Якість", - "Роздільна здатність завантажуваного відео.", - "Тема", - "Стиль вікна програми.", - "За моделями" - ] -} - -# Текущая локализация. -CURRENT_LOCALE = LOCALES["EN"] -# Тег текущего языка. -LanguageTag = None - -# Если устройство работает под управлением ОС семейства Linux. -if sys.platform in ["linux", "linux2"]: - # Получение тега текущего языка. - LanguageTag = locale.getlocale()[0].split('_')[0].upper() - -# Если устройство работает под управлением ОС семейства Windows. -elif sys.platform == "win32": - # Получение сведений о системе Windows. - WinDLL = ctypes.windll.kernel32 - WinDLL.GetUserDefaultUILanguage() - # Получение тега текущего языка. - LanguageTag = locale.windows_locale[WinDLL.GetUserDefaultUILanguage()].split('_')[0].upper() - -# Если существует локализация, переключиться на неё. -if LanguageTag in LOCALES.keys(): - CURRENT_LOCALE = LOCALES[LanguageTag] \ No newline at end of file diff --git a/Qt/Source/__init__.py b/Qt/Source/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Qt/main.py b/Qt/main.py deleted file mode 100644 index 8c6b861..0000000 --- a/Qt/main.py +++ /dev/null @@ -1,76 +0,0 @@ -from PyQt6.QtWidgets import QApplication, QStyleFactory -from Source.MainWindow import MainWindow -from PyQt6 import QtGui - -import ctypes -import json -import sys -import os - -#==========================================================================================# -# >>>>> ПРОВЕРКА ВЕРСИИ PYTHON <<<<< # -#==========================================================================================# - -# Минимальная требуемая версия Python. -PythonMinimalVersion = (3, 10) -# Проверка соответствия. -if sys.version_info < PythonMinimalVersion: sys.exit("Python %s.%s or later is required.\n" % PythonMinimalVersion) - -#==========================================================================================# -# >>>>> ЧТЕНИЕ НАСТРОЕК <<<<< # -#==========================================================================================# - -# Глобальные настройки. -Settings = { - "sort-by-models": False, - "save-directory": "", - "theme": 2, - "debug": False -} -# Словарь важных значений. -ComData = { - "version": "1.3.2", - "copyright": "Copyright © 2023-2024. DUB1401." -} - -# Проверка доступности файла настроек. -if os.path.exists("Settings.json"): - - # Открытие файла настроек. - with open("Settings.json", encoding = "utf-8") as FileRead: - # Чтение настроек. - Settings = json.load(FileRead) - - # Если директория для загрузки не указана. - if Settings["save-directory"] == "": - # Формирование пути. - Settings["save-directory"] = os.getcwd() + "/Downloads" - - # Если стандартной папки не существует, то создать. - if os.path.exists("Downloads") == False: - os.makedirs("Downloads") - -else: - # Выбро исключения. - raise Exception("Settings.json file not found.") - -# Если не включён режим отладки, то свернуть консоль при запуске. -if Settings["debug"] == False and sys.platform == "win32": - ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 6) - -#==========================================================================================# -# >>>>> ИНИЦИАЛИЗАЦИЯ ГРАФИЧЕСКОГО ИНТЕРФЕЙСА <<<<< # -#==========================================================================================# - -# Создание экземпляра приложения. -Application = QApplication(sys.argv) -# Установка икноки. -Application.setWindowIcon(QtGui.QIcon("icon.ico")) -# Открытие главного окна. -MainWindowObject = MainWindow(Application, ComData, Settings) -MainWindowObject.show() -# Запуск обработки приложения. -Application.exec() - -# Завершение работы скрипта. -sys.exit(Application.exit()) diff --git a/README.md b/README.md index cce6c91..62124b8 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ## Порядок установки и использования | Исполняемый файл Windows 1. Загрузить последний релиз исполняемой версии. Распаковать. -2. Запустить _main.exe_. Вставить в поле ввода список ссылок на видео и нажать кнопку загрузки. +2. Запустить _pornhub-dl.exe_. Вставить в поле ввода список ссылок на видео и нажать кнопку загрузки. 3. Дождаться скачивания видео в папку _Downloads_, в директории скрипта. ## Порядок установки и использования | Скрипт Python 1. Загрузить последний релиз скрипта. Распаковать. 2. Установить Python версии не старше 3.10. Рекомендуется добавить в PATH. -3. В среду исполнения установить следующие пакеты: [pyinstaller](https://github.com/pyinstaller/pyinstaller), [pyperclip](https://github.com/asweigart/pyperclip), [requests](https://github.com/psf/requests), [pyqt6](https://www.riverbankcomputing.com/software/pyqt/). +3. В среду исполнения установить следующие пакеты: [pyinstaller](https://github.com/pyinstaller/pyinstaller), [pyperclip](https://github.com/asweigart/pyperclip), [requests](https://github.com/psf/requests), [pyqt6](https://www.riverbankcomputing.com/software/pyqt). ``` pip install pyinstaller pip install pyperclip @@ -24,18 +24,18 @@ pip install -r requirements.txt 5. Дождаться скачивания видео в папку _Downloads_, в директории скрипта. # Скриншот -![2023-08-11_12-41-08](https://github.com/DUB1401/PornHub-Downloader/assets/40277356/c319a663-3969-4a2f-8b7b-94a3438b4e0c) +![Qt](Screenshots/Qt.png) # Сборка 1. Подготовить скрипт Python к работе согласно инструкции из порядка установки и использования. -2. Перейти в папку _Build_, внутри директории скрипта. +2. Перейти в каталог _Build/Windows_, внутри директории скрипта. 3. Запустить файл _build.bat_ и дождаться завершения работы. -4. Исполняемая версия будет помещена по адресу _Build/Release_ вместе со всеми зависимостями. +4. Исполняемая версия будет помещена по адресу _Build/Windows/Release_ вместе со всеми зависимостями. ## Локализация -Для добавления сторонней локализации необходимо отредактировать файл [Locale.py](Source/Locale.py): в `LOCALES` указываются списки используемых программой строк на целевом языке, ключём должен являться двухбуквенный тег языка в верхнем регистре по стандарту **ISO 639-1**. +Для добавления сторонней локализации необходимо отредактировать файл [Locales.json](Source/GUI/Qt/Locales.json): в нём указываются списки используемых программой строк на целевом языке, ключём должен являться двухбуквенный тег языка в верхнем регистре по стандарту **ISO 639-1**. -Доступные локализации: `EN`, `DE`, `PL`, `RU`, `UK`. +Доступные локализации: `EN`, `RU`. ## Версии поставляемых бинарных файлов | Файл | Версия | Источник | @@ -47,4 +47,4 @@ pip install -r requirements.txt # Благодарность * [@yt-dlp](https://github.com/yt-dlp) – библиотека загрузки потокового видео. -_Copyright © DUB1401. 2023._ \ No newline at end of file +_Copyright © DUB1401. 2023-2024._ \ No newline at end of file diff --git a/Screenshots/Qt.png b/Screenshots/Qt.png new file mode 100644 index 0000000..1da8324 Binary files /dev/null and b/Screenshots/Qt.png differ diff --git a/Settings.json b/Settings.json index 8a156f4..d8b5ad8 100644 --- a/Settings.json +++ b/Settings.json @@ -1,7 +1,7 @@ { "sort-by-models": false, - "save-directory": "", - "cuality": 2, - "debug": true, + "downloads-directory": "", + "cuality": 5, + "debug": false, "advertisement": "https://xn--80aaalhzvfe9b4a.xn--80asehdb/" } \ No newline at end of file diff --git a/Source/Core.py b/Source/Core.py new file mode 100644 index 0000000..10d6007 --- /dev/null +++ b/Source/Core.py @@ -0,0 +1 @@ +прив \ No newline at end of file diff --git a/GTK4/Source/MainWindow.py b/Source/GUI/GTK4/Source/MainWindow.py similarity index 100% rename from GTK4/Source/MainWindow.py rename to Source/GUI/GTK4/Source/MainWindow.py diff --git a/GTK4/main.py b/Source/GUI/GTK4/main.py similarity index 100% rename from GTK4/main.py rename to Source/GUI/GTK4/main.py diff --git a/Source/GUI/Qt/Locale.py b/Source/GUI/Qt/Locale.py new file mode 100644 index 0000000..cd73df5 --- /dev/null +++ b/Source/GUI/Qt/Locale.py @@ -0,0 +1,30 @@ +from dublib.Methods import ReadJSON + +import ctypes +import locale +import sys + +# Словарь локализаций. +LOCALES = ReadJSON("Source/GUI/Qt/Locales.json") + +# Текущая локализация. +CURRENT_LOCALE = LOCALES["EN"] +# Тег текущего языка. +LanguageTag = None + +# Если устройство работает под управлением ОС семейства Linux. +if sys.platform in ["linux", "linux2"]: + # Получение тега текущего языка. + LanguageTag = locale.getlocale()[0].split('_')[0].upper() + +# Если устройство работает под управлением ОС семейства Windows. +elif sys.platform == "win32": + # Получение сведений о системе Windows. + WinDLL = ctypes.windll.kernel32 + WinDLL.GetUserDefaultUILanguage() + # Получение тега текущего языка. + LanguageTag = locale.windows_locale[WinDLL.GetUserDefaultUILanguage()].split('_')[0].upper() + +# Если существует локализация, переключиться на неё. +if LanguageTag in LOCALES.keys(): + CURRENT_LOCALE = LOCALES[LanguageTag] \ No newline at end of file diff --git a/Source/GUI/Qt/Locales.json b/Source/GUI/Qt/Locales.json new file mode 100644 index 0000000..de2c70d --- /dev/null +++ b/Source/GUI/Qt/Locales.json @@ -0,0 +1,32 @@ +{ + "EN": [ + "Advertisement", + "Clear", + "Copy output", + "Download", + "Paste here links to videos", + "Output logs", + "Paste links", + "Settings", + "Cuality", + "Resolution of the downloaded video.", + "Theme", + "Style of the program window.", + "Sort by models" + ], + "RU": [ + "Реклама", + "Очистить", + "Копировать логи", + "Скачать", + "Вставьте сюда ссылки на видео", + "Логи", + "Вставить ссылки", + "Настройки", + "Качество", + "Разрешение загружаемого видео.", + "Тема", + "Стиль окна программы.", + "По моделям" + ] +} \ No newline at end of file diff --git a/Qt/Source/QLabelAdvertisement.py b/Source/GUI/Qt/QLabelAdvertisement.py similarity index 100% rename from Qt/Source/QLabelAdvertisement.py rename to Source/GUI/Qt/QLabelAdvertisement.py diff --git a/Qt/Source/MainWindow.py b/Source/GUI/Qt/QtWindow.py similarity index 97% rename from Qt/Source/MainWindow.py rename to Source/GUI/Qt/QtWindow.py index e7e754f..f0d2678 100644 --- a/Qt/Source/MainWindow.py +++ b/Source/GUI/Qt/QtWindow.py @@ -1,3 +1,5 @@ +from PyQt6.QtWidgets import QApplication, QStyleFactory +from PyQt6 import QtGui from PyQt6.QtWidgets import ( QApplication, QCheckBox, @@ -12,10 +14,10 @@ QVBoxLayout ) from PyQt6.QtGui import QCursor, QDesktopServices, QMovie, QTextCursor -from Source.QLabelAdvertisement import QLabelAdvertisement +from Source.GUI.Qt.QLabelAdvertisement import QLabelAdvertisement from PyQt6.QtCore import Qt,QSize, QThread, QUrl -from Source.Locale import CURRENT_LOCALE -from Source.yt_dlp import yt_dlp +from Source.GUI.Qt.Locale import CURRENT_LOCALE +from Source.GUI.Qt.yt_dlp import yt_dlp import pyperclip import json @@ -24,7 +26,7 @@ import re # Обработчик взаимодействий с главным окном. -class MainWindow(QMainWindow): +class QtWindow(QMainWindow): #==========================================================================================# # >>>>> СВОЙСТВА <<<<< # @@ -152,8 +154,8 @@ def __SaveSetting(self, Key: str, Value): Bufer = self.__Settings.copy() # Удаление пути к стандартной папке загрузок. - if Bufer["save-directory"] == os.getcwd() + "/Downloads": - Bufer["save-directory"] = "" + if Bufer["downloads-directory"] == os.getcwd() + "/Downloads": + Bufer["downloads-directory"] = "" # Сохранение настройки. with open("Settings.json", "w", encoding = "utf-8") as FileWrite: @@ -286,7 +288,7 @@ def __CreateSettingsGroupUI(self): # Создание объекта GUI: селектор качества. CualitySelecter = QComboBox(self) - CualitySelecter.addItems(["4K", "2K", "1080", "720", "480", "240"]) + CualitySelecter.addItems(["4K", "2K", "1080", "720", "480", "360", "240"]) CualitySelecter.setCurrentIndex(self.__Settings["cuality"]) CualitySelecter.currentIndexChanged.connect(lambda: self.__SaveSetting("cuality", CualitySelecter.currentIndex())) CualitySelecter.resize(180, 40) @@ -387,7 +389,7 @@ def __RemoveRepeatedLinks(self): # Обрабатывает начало загрузки видео. def __StartDownloading(self): # Директория загрузки. - SaveDirectory = self.__Settings["save-directory"] + SaveDirectory = self.__Settings["downloads-directory"] # Сохранение времени начала загрузки. self.__StartTime = time.time() diff --git a/Qt/Source/yt_dlp.py b/Source/GUI/Qt/yt_dlp.py similarity index 94% rename from Qt/Source/yt_dlp.py rename to Source/GUI/Qt/yt_dlp.py index 912b5c5..049a9f8 100644 --- a/Qt/Source/yt_dlp.py +++ b/Source/GUI/Qt/yt_dlp.py @@ -2,6 +2,7 @@ import subprocess import json +import sys import os # Потоковый обработчик взаимодейтсвий с библиотекой pornhub_dl. @@ -37,7 +38,7 @@ def __init__(self, SaveDirectory: str, Link: str, SortByUploader: bool, Cuality: #---> Генерация свойств. #==========================================================================================# - self.__CurrentDirectory = os.getcwd() + self.__CurrentDirectory = os.getcwd().replace("\\", "/") self.__SaveDirectory = SaveDirectory self.__Link = Link self.__SortByUploader = SortByUploader @@ -45,12 +46,13 @@ def __init__(self, SaveDirectory: str, Link: str, SortByUploader: bool, Cuality: # Возвращает словарь описания предварительного процессирования yt-dlp. def dump(self) -> dict: + # Расширение файла. + Type = ".exe" if sys.platform == "win32" else "" # Дампирование видео. - Result = subprocess.getoutput(f"{self.__CurrentDirectory}/yt-dlp/yt-dlp --dump-json {self.__Link}") + Result = subprocess.getoutput(f"{self.__CurrentDirectory}/yt-dlp/yt-dlp{Type} --dump-json {self.__Link}") # Если нет ошибки дампирования. if Result.startswith("ERROR") == False: - print(Result) # Получение дампа через вывод yt-dlp. self.__Dump = json.loads(Result) diff --git a/Source/Window.py b/Source/Window.py new file mode 100644 index 0000000..4cbc255 --- /dev/null +++ b/Source/Window.py @@ -0,0 +1,75 @@ +from Source.GUI.Qt.QtWindow import QtWindow +from PyQt6.QtWidgets import QApplication +from PyQt6 import QtGui + +import ctypes +import enum +import sys + +#==========================================================================================# +# >>>>> ДОПОЛНИТЕЛЬНЫЕ ТИПЫ ДАННЫХ <<<<< # +#==========================================================================================# + +# Типы графических библиотек. +class Toolkits(enum.Enum): + GTK = "gtk" + Qt = "qt" + +#==========================================================================================# +# >>>>> ОСНОВНОЙ КЛАСС <<<<< # +#==========================================================================================# + +# Дескриптор окна. +class Window: + + # Сворачивает терминал Windows. + def __MinimizeCMD(self): + # Если не включён режим отладки, свернуть консоль. + if self.__Settings["debug"] == False and sys.platform == "win32": ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), 6) + + # Инициализирует приложение Qt. + def __InitApplication_Qt(self): + # Создание экземпляра приложения. + self.__Application = QApplication(sys.argv) + # Настройка внешнего вида. + self.__Application.setStyle("Fusion") + self.__Application.setWindowIcon(QtGui.QIcon("icon.ico")) + # Создание окна. + self.__Window = QtWindow(self.__Application, self.__Veriables, self.__Settings) + + # Конструктор. + def __init__(self, variables: dict, settings: dict): + + #---> Генерация динамических свойств. + #==========================================================================================# + # Словарь важных значений. + self.__Veriables = variables + # Глобальные настройки. + self.__Settings = settings + # Экзмепляр приложения. + self.__Application = None + # Экземпляр окна. + self.__Window = None + + # Отображает окно. + def show(self, toolkit: Toolkits) -> int: + # Код завершения. + ExitCode = 0 + + # Если используется Qt: + if toolkit == Toolkits.Qt: + # Инициализация приложения. + self.__InitApplication_Qt() + # Открытие окна. + self.__Window.show() + # Сворачивание терминала на Windows. + self.__MinimizeCMD() + # Запуск приложения Qt. + ExitCode = self.__Application.exec() + + # Если используется GTK: + if toolkit == Toolkits.GTK: + # Если используется ОС семейства Windows, выбросить исключение. + if sys.platform == "win32": raise ImportError("GTK isn't support on Windows.") + + return ExitCode \ No newline at end of file diff --git a/Qt/icon.ico b/icon.ico similarity index 100% rename from Qt/icon.ico rename to icon.ico diff --git a/main.py b/main.py new file mode 100644 index 0000000..2bc4363 --- /dev/null +++ b/main.py @@ -0,0 +1,72 @@ +from dublib.Methods import CheckPythonMinimalVersion, ReadJSON +from dublib.Terminalyzer import Command, Terminalyzer +from Source.Window import Window, Toolkits + +import ctypes +import json +import sys +import os + +#==========================================================================================# +# >>>>> ИНИЦИАЛИЗАЦИЯ СКРИПТА <<<<< # +#==========================================================================================# + +# Проверка минимальной требуемой версии. +CheckPythonMinimalVersion(3, 10) +# Словарь важных значений. +VARIABLES = { + "version": "1.4.0", + "copyright": "Copyright © 2023-2024. DUB1401." +} + +#==========================================================================================# +# >>>>> ЧТЕНИЕ НАСТРОЕК <<<<< # +#==========================================================================================# + +# Чтение настроек. +Settings = ReadJSON("Settings.json") + +# Если директория для загрузки не указана. +if Settings["downloads-directory"] == "": + # Формирование пути. + Settings["downloads-directory"] = os.getcwd() + "/Downloads" + # Если стандартной папки не существует, создать. + if os.path.exists("Downloads") == False: os.makedirs("Downloads") + +#==========================================================================================# +# >>>>> НАСТРОЙКА ОБРАБОТЧИКА КОМАНД <<<<< # +#==========================================================================================# + +# Список описаний обрабатываемых команд. +CommandsList = list() + +# Создание команды: run. +COM_run = Command("run") +COM_run.add_flag_position(["qt", "gtk"]) +CommandsList.append(COM_run) + +# Инициализация обработчика консольных аргументов. +CAC = Terminalyzer() +# Получение информации о проверке команд. +CommandDataStruct = CAC.check_commands(CommandsList) + +#==========================================================================================# +# >>>>> ОБРАБОТКА КОМАНД <<<<< # +#==========================================================================================# + +# Запуск стандартного окна. +WindowObject = Window(VARIABLES, Settings) +# Стандартная графическая библиотека. +Toolkit = Toolkits.Qt + +# Обработка отсутствия команды. +if CommandDataStruct == None: + # Запуск стандартного окна. + WindowObject.show(Toolkit) + +# Обработка команды: run +if CommandDataStruct.name == "run": + # Если указана GTK, выполнить запуск с её использованием. + if "gtk" in CommandDataStruct.flags: Toolkit = Toolkits.GTK + # Запуск окна. + WindowObject.show(Toolkit) \ No newline at end of file diff --git a/Qt/yt-dlp/ffmpeg.exe b/yt-dlp/ffmpeg.exe similarity index 100% rename from Qt/yt-dlp/ffmpeg.exe rename to yt-dlp/ffmpeg.exe diff --git a/Qt/yt-dlp/ffprobe.exe b/yt-dlp/ffprobe.exe similarity index 100% rename from Qt/yt-dlp/ffprobe.exe rename to yt-dlp/ffprobe.exe diff --git a/Qt/yt-dlp/yt-dlp b/yt-dlp/yt-dlp old mode 100755 new mode 100644 similarity index 100% rename from Qt/yt-dlp/yt-dlp rename to yt-dlp/yt-dlp diff --git a/yt-dlp/yt-dlp.exe b/yt-dlp/yt-dlp.exe new file mode 100644 index 0000000..dc0d6da Binary files /dev/null and b/yt-dlp/yt-dlp.exe differ