Files
YT_Download_Script/install_dependencies.py
T

261 lines
8.3 KiB
Python
Raw Normal View History

2026-09-13 19:56:37 +01:00
#!/usr/bin/env python3
"""
Installer for YouTube Downloader dependencies.
Installs: yt-dlp, ffmpeg
Supports: Windows, macOS, Linux (Debian/Ubuntu, Fedora/RHEL, Arch)
"""
import os
import sys
import shutil
import subprocess
import platform
# ── Helpers ────────────────────────────────────────────────────────────────────
def run(cmd: list[str], check=True) -> subprocess.CompletedProcess:
print(f" → {' '.join(cmd)}")
return subprocess.run(cmd, check=check)
def ok(msg: str):
print(f" ✅ {msg}")
def info(msg: str):
print(f" {msg}")
def warn(msg: str):
print(f" ⚠️ {msg}")
def fail(msg: str):
print(f" ❌ {msg}")
sys.exit(1)
def section(title: str):
print(f"\n{'─' * 50}")
print(f" {title}")
print(f"{'─' * 50}")
# ── Platform detection ─────────────────────────────────────────────────────────
OS = platform.system() # 'Windows', 'Darwin', 'Linux'
IS_WIN = OS == "Windows"
IS_MAC = OS == "Darwin"
IS_LINUX = OS == "Linux"
def linux_distro() -> str:
"""Return 'debian', 'fedora', 'arch', or 'unknown'."""
if shutil.which("apt-get"):
return "debian"
if shutil.which("dnf") or shutil.which("yum"):
return "fedora"
if shutil.which("pacman"):
return "arch"
return "unknown"
# ── Python / pip check ─────────────────────────────────────────────────────────
def check_python():
section("Checking Python")
major, minor = sys.version_info[:2]
print(f" Python {major}.{minor} detected")
if major < 3 or (major == 3 and minor < 8):
fail("Python 3.8+ is required. Please upgrade and re-run this script.")
ok("Python version is compatible")
def ensure_pip():
section("Checking pip")
try:
import pip # noqa: F401
ok("pip is available")
except ImportError:
info("pip not found — installing via ensurepip...")
run([sys.executable, "-m", "ensurepip", "--upgrade"])
ok("pip installed")
# Always upgrade pip to avoid resolver issues
run([sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
ok("pip is up to date")
# ── yt-dlp ─────────────────────────────────────────────────────────────────────
def install_ytdlp():
section("Installing yt-dlp")
run([sys.executable, "-m", "pip", "install", "--upgrade", "yt-dlp"])
ok("yt-dlp installed/updated")
# ── ffmpeg ─────────────────────────────────────────────────────────────────────
def ffmpeg_already_installed() -> bool:
if shutil.which("ffmpeg"):
result = subprocess.run(
["ffmpeg", "-version"], capture_output=True, text=True, check=False
)
version_line = result.stdout.splitlines()[0] if result.stdout else "unknown"
info(f"ffmpeg already installed: {version_line}")
return True
return False
def install_ffmpeg_windows():
"""
On Windows, download the pre-built ffmpeg binary via winget or chocolatey.
Falls back to manual instructions if neither is available.
"""
if shutil.which("winget"):
info("Using winget to install ffmpeg...")
run(["winget", "install", "--id", "Gyan.FFmpeg", "-e", "--silent"])
elif shutil.which("choco"):
info("Using Chocolatey to install ffmpeg...")
run(["choco", "install", "ffmpeg", "-y"])
elif shutil.which("scoop"):
info("Using Scoop to install ffmpeg...")
run(["scoop", "install", "ffmpeg"])
else:
warn("No package manager found (winget / choco / scoop).")
print("""
Please install ffmpeg manually:
1. Go to https://www.gyan.dev/ffmpeg/builds/
2. Download the latest 'release essentials' zip
3. Extract it and add the 'bin' folder to your PATH
""")
return
ok("ffmpeg installed")
def install_ffmpeg_mac():
if shutil.which("brew"):
info("Using Homebrew to install ffmpeg...")
run(["brew", "install", "ffmpeg"])
elif shutil.which("port"):
info("Using MacPorts to install ffmpeg...")
run(["sudo", "port", "install", "ffmpeg"])
else:
warn("Homebrew not found. Installing Homebrew first...")
install_cmd = (
'/bin/bash -c "$(curl -fsSL '
'https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
)
subprocess.run(install_cmd, shell=True, check=True)
run(["brew", "install", "ffmpeg"])
ok("ffmpeg installed")
def install_ffmpeg_linux():
distro = linux_distro()
if distro == "debian":
info("Using apt-get (Debian/Ubuntu)...")
run(["sudo", "apt-get", "update", "-qq"])
run(["sudo", "apt-get", "install", "-y", "ffmpeg"])
elif distro == "fedora":
info("Using dnf (Fedora/RHEL)...")
# ffmpeg lives in RPM Fusion on Fedora
run(["sudo", "dnf", "install", "-y",
"https://download1.rpmfusion.org/free/fedora/"
"rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm"], check=False)
run(["sudo", "dnf", "install", "-y", "ffmpeg"])
elif distro == "arch":
info("Using pacman (Arch Linux)...")
run(["sudo", "pacman", "-Sy", "--noconfirm", "ffmpeg"])
else:
warn("Unrecognised Linux distro — cannot auto-install ffmpeg.")
print("""
Please install ffmpeg with your distro's package manager, e.g.:
sudo apt-get install ffmpeg # Debian / Ubuntu
sudo dnf install ffmpeg # Fedora
sudo pacman -S ffmpeg # Arch
""")
return
ok("ffmpeg installed")
def install_ffmpeg():
section("Installing ffmpeg")
if ffmpeg_already_installed():
ok("Skipping — ffmpeg is already installed")
return
if IS_WIN:
install_ffmpeg_windows()
elif IS_MAC:
install_ffmpeg_mac()
elif IS_LINUX:
install_ffmpeg_linux()
else:
warn(f"Unsupported OS: {OS}")
# ── Final verification ─────────────────────────────────────────────────────────
def verify():
section("Verification")
all_good = True
# yt-dlp
try:
import yt_dlp
ok(f"yt-dlp {yt_dlp.version.__version__}")
except ImportError:
fail("yt-dlp import failed after installation!")
all_good = False
# ffmpeg
if shutil.which("ffmpeg"):
result = subprocess.run(
["ffmpeg", "-version"], capture_output=True, text=True, check=False
)
version_line = result.stdout.splitlines()[0] if result.stdout else "unknown version"
ok(f"ffmpeg — {version_line}")
else:
warn("ffmpeg not found in PATH. High-quality merging may not work.")
warn("You can still download videos but 1080p/4K may be unavailable.")
all_good = False
return all_good
# ── Main ───────────────────────────────────────────────────────────────────────
def main():
print("\n" + "=" * 50)
print(" YouTube Downloader — Dependency Installer")
print("=" * 50)
print(f" OS : {OS} ({platform.machine()})")
print(f" Python : {sys.version.split()[0]}")
check_python()
ensure_pip()
install_ytdlp()
install_ffmpeg()
all_good = verify()
print("\n" + "=" * 50)
if all_good:
print(" 🎉 All dependencies installed successfully!")
print(" Run python yt_downloader.py to start downloading.")
else:
print(" ⚠️ Setup finished with warnings (see above).")
print("=" * 50 + "\n")
if __name__ == "__main__":
main()