93 lines
3.8 KiB
Python
93 lines
3.8 KiB
Python
import os
|
|
import requests
|
|
import zipfile
|
|
import shutil
|
|
from PyQt6.QtCore import QThread, pyqtSignal
|
|
|
|
# URL de yt-dlp ejecutable directo
|
|
URL_YTDLP = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe"
|
|
|
|
class DependencyChecker(QThread):
|
|
progress_signal = pyqtSignal(str, int) # (Mensaje, Porcentaje)
|
|
finished_signal = pyqtSignal()
|
|
|
|
def __init__(self, bin_dir="bin"):
|
|
super().__init__()
|
|
self.bin_dir = os.path.abspath(bin_dir)
|
|
|
|
def run(self):
|
|
os.makedirs(self.bin_dir, exist_ok=True)
|
|
|
|
ytdlp_path = os.path.join(self.bin_dir, "yt-dlp.exe")
|
|
ffmpeg_path = os.path.join(self.bin_dir, "ffmpeg.exe")
|
|
ffprobe_path = os.path.join(self.bin_dir, "ffprobe.exe")
|
|
|
|
# Limpiar archivos corruptos o de tamaño inferior a 1 MB
|
|
self.cleanup_invalid_files([ytdlp_path, ffmpeg_path, ffprobe_path])
|
|
|
|
# 1. Verificar / Descargar yt-dlp.exe
|
|
if not os.path.exists(ytdlp_path):
|
|
self.download_file("yt-dlp.exe", URL_YTDLP, ytdlp_path)
|
|
|
|
# 2. Verificar / Descargar FFmpeg y FFprobe reales desde la API de GitHub
|
|
if not os.path.exists(ffmpeg_path) or not os.path.exists(ffprobe_path):
|
|
self.download_ffmpeg_suite()
|
|
|
|
self.progress_signal.emit("Todos los componentes están listos.", 100)
|
|
self.finished_signal.emit()
|
|
|
|
def cleanup_invalid_files(self, paths):
|
|
for p in paths:
|
|
if os.path.exists(p) and os.path.getsize(p) < 1000000: # Menor a ~1 MB
|
|
try:
|
|
os.remove(p)
|
|
except Exception:
|
|
pass
|
|
|
|
def download_file(self, name, url, save_path):
|
|
headers = {"User-Agent": "Mozilla/5.0"}
|
|
response = requests.get(url, headers=headers, stream=True, allow_redirects=True)
|
|
total_size = int(response.headers.get('content-length', 0))
|
|
downloaded = 0
|
|
|
|
with open(save_path, 'wb') as file:
|
|
for chunk in response.iter_content(chunk_size=16384):
|
|
if chunk:
|
|
file.write(chunk)
|
|
downloaded += len(chunk)
|
|
if total_size > 0:
|
|
percent = int((downloaded / total_size) * 100)
|
|
self.progress_signal.emit(f"Descargando {name}...", percent)
|
|
|
|
def download_ffmpeg_suite(self):
|
|
self.progress_signal.emit("Buscando versión de FFmpeg...", 5)
|
|
headers = {"User-Agent": "Mozilla/5.0"}
|
|
|
|
# Consultar la API de GitHub de GyanD/codexffmpeg para obtener la URL directa del ZIP
|
|
api_url = "https://api.github.com/repos/GyanD/codexffmpeg/releases/latest"
|
|
r = requests.get(api_url, headers=headers).json()
|
|
|
|
download_url = None
|
|
for asset in r.get("assets", []):
|
|
if asset["name"].endswith("essentials_build.zip") or asset["name"].endswith("full_build.zip"):
|
|
download_url = asset["browser_download_url"]
|
|
break
|
|
|
|
if not download_url:
|
|
# URL de respaldo estática si falla la API
|
|
download_url = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
|
|
|
|
zip_path = os.path.join(self.bin_dir, "ffmpeg.zip")
|
|
self.download_file("FFmpeg Suite (ZIP)", download_url, zip_path)
|
|
|
|
self.progress_signal.emit("Extrayendo FFmpeg y FFprobe...", 90)
|
|
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
for member in zip_ref.namelist():
|
|
filename = os.path.basename(member)
|
|
if filename in ["ffmpeg.exe", "ffprobe.exe"]:
|
|
target_path = os.path.join(self.bin_dir, filename)
|
|
with zip_ref.open(member) as source, open(target_path, "wb") as target:
|
|
shutil.copyfileobj(source, target)
|
|
|
|
if os.path.exists(zip_path):
|
|
os.remove(zip_path) |