A modern, production-grade YouTube downloader with a polished GUI,
multi-strategy retry engine, and 8K → 720p quality cascade.
- Overview
- What Changed from v1 → v3
- Features
- System Requirements
- Installation
- Usage Guide
- Quality Presets
- Multi-Strategy Retry Engine
- Configuration Reference
- Architecture
- Production Deployment
- Troubleshooting
- Roadmap
- Disclaimer
- License
YouTube Downloader Pro is a desktop application for downloading YouTube videos, playlists, and audio. It wraps yt-dlp with an intelligent multi-strategy retry engine that automatically recovers from transient HTTP errors (403, 429, 503, timeouts) by cycling through up to 4 video and 3 audio fallback format strategies — ensuring downloads complete reliably even on unstable or throttled networks.
The application provides a clean four-tab interface (Download · Queue · History · Settings) built with CustomTkinter, offering full control over quality, format, subtitles, SponsorBlock, proxy, cookies, and 25+ other preferences. All settings persist across sessions in a JSON configuration file.
- Resilient downloads — subtitle/thumbnail failures are gracefully skipped; the video always downloads
- Smart error classification — retryable errors (403, 429, 503) trigger automatic fallback; non-retryable errors (private, deleted) stop immediately
- 5 quality presets — Maximum (8K→720p with HDR/high-FPS preference), High (1080p), Balanced (720p), Audio Only (6 codecs), Video Only (no audio)
- Concurrent downloads — semaphore-based parallelism (1–5 simultaneous) with per-video fragment parallelism (1–8)
- Cross-platform — Windows, macOS, and Linux with platform-native file manager integration
| Area | v1.0 | v2.0 | v3.0 (current) |
|---|---|---|---|
| Architecture | Single 600-line file | 11-module package | 11-module package with dataclasses, enums, type hints |
| UI Framework | tkinter | CustomTkinter | CustomTkinter with segmented buttons, tabbed interface, dark/light/system themes |
| Download Engine | Basic yt-dlp call | Queue with concurrency | Multi-strategy retry with 7 fallback strategies and graceful degradation |
| Quality | 3 presets | 3 presets | 5 presets (Maximum 8K→720p, High, Balanced, Audio Only, Video Only) |
| Audio | MP3 only | MP3 only | MP3, OPUS, FLAC, WAV, AAC, Vorbis — configurable bitrate |
| Network | None | None | Proxy (SOCKS5/HTTP), speed limiting, cookies, configurable timeouts |
| Resilience | No retry | Basic retry | 4+3 fallback strategies, smart error classification, graceful subtitle/thumbnail skip |
| Features | Download only | + Queue, settings | + SponsorBlock, subtitles, chapters, thumbnails, metadata, playlist mode, video analysis |
| History | None | JSON file | Persistent JSON with search, re-download, copy URL, export |
-
Downloads no longer fail on non-critical errors. In v2.0, a single subtitle HTTP 429 error would kill the entire download. v3.0 sets
ignoreerrors: Truewith a custom yt-dlp logger that captures and classifies errors — subtitles/thumbnails fail gracefully while truly fatal errors (video unavailable, private, deleted) are still detected and reported. -
Fallback strategies preserve quality preferences. When the engine retries with a simpler format string, v3.0 still applies the active quality preset's
format_sortand codec preferences, so fallback downloads maintain resolution and codec quality rather than falling back to arbitrary formats. -
Partial playlist success is recognized. A playlist of 100 videos where 2 are unavailable now reports success after downloading 98 — instead of failing the entire batch.
-
The engine is fully observable. All yt-dlp warnings and errors are forwarded to the app's log box, giving users real-time visibility into what's happening during a download.
-
The UI is production-quality. Theme switching (dark/light/system) with instant preview, cookies file browser, concurrent fragment control, and 25+ persistent settings.
| Category | Details |
|---|---|
| Modern GUI | Dark / light / system themes, tabbed interface, segmented quality selector |
| Quality Cascade | 8K → 4K → 2K → 1080p → 720p → best available, with HDR and high-FPS preference |
| 5 Quality Presets | Maximum (8K→720p), High (1080p), Balanced (720p), Audio Only, Video Only |
| Multi-Strategy Retry | 4 video + 3 audio fallback strategies on HTTP 403/429/503/timeout/reset |
| Graceful Degradation | Subtitle/thumbnail download failures are silently skipped — the video always downloads |
| Audio Codecs | MP3, OPUS, FLAC, WAV, AAC, Vorbis — configurable bitrate (128–320 kbps) |
| Download Queue | Visual queue with per-task progress, retry, cancel, and open-folder buttons |
| Persistent History | Searchable history (up to 1,000 entries) with re-download, copy URL, and JSON export |
| SponsorBlock | Automatic sponsor/self-promo/interaction segment removal |
| Subtitles | Multi-language subtitle download and embedding (comma-separated ISO codes) |
| Output Formats | MP4, MKV, WebM, MP3, OPUS, FLAC, WAV — with thumbnail, metadata, and chapter embedding |
| Network | SOCKS5/HTTP proxy, speed limiting, configurable socket timeout, cookies file browser |
| Performance | Concurrent fragment downloads (1–8), semaphore-based concurrency (1–5), 10 MB HTTP chunks |
| Video Analysis | Pre-download metadata: title, duration, resolution, FPS, HDR, view count, file size estimate |
| Playlist Support | Full playlist download with numbered output (001 - Title.ext), automatic URL detection |
| URL Validation | 15+ YouTube URL patterns: watch, shorts, live, embed, music, channel, handle, clips, playlists |
| Disk Safety | Free space checking before download with configurable safety margin |
| Cross-Platform | Windows, macOS, Linux — platform-native file manager integration |
| 25+ Settings | All preferences saved to ~/.ytdlp_gui/settings.json with one-click Reset to Defaults |
| Component | Minimum | Recommended |
|---|---|---|
| Python | 3.10 | 3.12+ |
| OS | Windows 10, macOS 12, Ubuntu 20.04 | Latest stable release |
| FFmpeg | 5.0 | 7.0+ (for AV1/HDR support) |
| RAM | 256 MB | 512 MB+ |
| Disk | 100 MB (application) | 10+ GB free (for video storage) |
| Network | Any internet connection | Broadband recommended |
| Package | Version | Purpose |
|---|---|---|
| yt-dlp | ≥ 2024.1.0 | YouTube extraction, downloading, and post-processing |
| customtkinter | ≥ 5.2.0 | Modern cross-platform GUI framework |
FFmpeg is a system dependency (not a Python package) required for merging video/audio streams, transcoding, and embedding thumbnails/subtitles.
Download from python.org. On Windows, check "Add Python to PATH" during installation.
python --version # verify: should print 3.10 or newerOption A — Clone with Git:
git clone https://github.com/Adarsh-61/YouTubeDownloaderPro.git
cd YouTubeDownloaderProOption B — Download ZIP: Download from the repository page and extract to a folder.
pip install -r requirements.txtThis installs yt-dlp and customtkinter. All other dependencies are part of the Python standard library.
FFmpeg is required for merging video and audio streams, audio extraction, thumbnail/subtitle embedding, and format remuxing.
Windows
- Download from gyan.dev/ffmpeg (choose the full build)
- Extract the archive
- Add the
binfolder to your system PATH:- Settings → System → About → Advanced system settings → Environment Variables
- Under System variables, select
Path→ Edit → New - Paste the full path to the
binfolder (e.g.C:\ffmpeg\bin)
- Open a new terminal and verify:
ffmpeg -version
macOS
brew install ffmpegLinux (Debian/Ubuntu)
sudo apt update && sudo apt install ffmpegLinux (Fedora)
sudo dnf install ffmpegpython youtube_downloader.pyOr run as a Python module:
python -m ytdlp_guiThe status bar at the bottom of the window confirms FFmpeg and yt-dlp detection.
- Paste a URL — Copy a YouTube URL and click Paste (or type/paste directly and press
Enter) - Select quality — Choose from the segmented preset bar: Maximum, High, Balanced, Audio Only, or Video Only
- Choose format — Pick the output container (MP4, MKV, WebM for video; MP3, OPUS, FLAC, WAV for audio)
- Toggle options — Enable or disable Subtitles, Thumbnail, Metadata, Chapters, SponsorBlock, Playlist mode
- Set output directory — Browse or type the destination folder
- Click Start Download — Progress is shown in real time (speed, ETA, bytes)
Click Analyze to preview metadata without starting a download:
- Title, duration, uploader, view count
- Maximum available resolution and FPS
- HDR availability
- Estimated file size
Switch to the Queue tab to see all active, queued, and completed downloads:
- Cancel (✕) — Stop a running download
- Retry (↻) — Re-submit a failed download with the same settings
- Open Folder (📂) — Open the output directory in your file manager
- Clear Done — Remove all completed/failed/canceled entries from the list
The History tab stores up to 1,000 past downloads across sessions:
- Search — Filter by title or URL (250ms debounce for smooth typing)
- Re-download (↻) — One click to populate the Download tab with the URL
- Copy URL (📋) — Copy to clipboard
- Export — Save the full history as a JSON file
- Paste a playlist URL — the app auto-detects URLs containing
list= - Playlist mode is automatically enabled (or toggle manually)
- Files are saved as
001 - Title.ext,002 - Title.ext, etc., inside a folder named after the playlist
Some videos require authentication (age-restricted, members-only):
- Install a browser extension like "Get cookies.txt LOCALLY"
- Export your YouTube cookies and save as
cookies.txt - In the app, go to Settings → Cookies file → Browse and select the file
| Preset | Resolution | Container | Codec Preference | Notes |
|---|---|---|---|---|
| Maximum | 8K → 4K → 2K → 1080p → 720p | MKV | AV1 → VP9.2 → VP9 → HEVC → H.264 | Best available quality, HDR and high-FPS preferred, format_sort_force enabled |
| High | ≤ 1080p | MP4 | H.264 → HEVC | Wide device compatibility |
| Balanced | ≤ 720p | MP4 | Auto | Smallest reasonable file size |
| Audio Only | — | MP3/OPUS/FLAC/WAV/AAC | Configurable | Codec and bitrate selectable (128–320 kbps) |
| Video Only | 8K → 720p | MP4 | AV1 → VP9 → HEVC → H.264 | Video stream without audio, useful for editing |
When a download fails with a retryable error, the engine cycles through fallback format strategies instead of giving up. Non-retryable errors immediately stop the fallback chain. Fallback strategies inherit the active preset's format_sort and codec preferences, so retried downloads maintain quality.
| Type | Examples | Engine Behavior |
|---|---|---|
| Retryable | HTTP 403 (CDN block), 429 (rate limit), 503 (server busy), timeout, connection reset, incomplete data | Tries next fallback strategy automatically |
| Non-retryable | Video unavailable, private, deleted, copyright takedown | Stops immediately, reports the error |
| Non-critical | Subtitle 429, thumbnail download failure | Silently skipped — video still downloads |
| # | Strategy | Format String | Why It Helps |
|---|---|---|---|
| 1 | Resolution cascade | bv*[height>=4320]+ba/…/bv*+ba/best |
Explicit resolution preference with all heights |
| 2 | Simple best | bestvideo+bestaudio/best |
Some extractors handle simple expressions better |
| 3 | Progressive only | best[height>=1080]/best[height>=720]/best |
Avoids merge step, bypasses some CDN 403 errors |
| 4 | Last resort | best |
Accepts any available format |
| # | Strategy | Format String |
|---|---|---|
| 1 | Codec preference | bestaudio[ext=webm]/bestaudio[ext=m4a]/bestaudio/best |
| 2 | Generic best | bestaudio/best |
| 3 | Last resort | best |
All settings persist in ~/.ytdlp_gui/settings.json and are editable from the Settings tab.
| Setting | Default | Description |
|---|---|---|
| Theme | light |
dark, light, or system (follows OS) — instant preview on save |
| Window size | 1100 × 820 | Automatically saved on exit |
| Setting | Default | Description |
|---|---|---|
| Quality preset | Maximum | Default quality for new downloads |
| Output format | MP4 | Default container format |
| Audio codec | MP3 | Codec for audio-only extraction |
| Audio bitrate | 320 kbps | Bitrate for lossy audio codecs (128–320) |
| Setting | Default | Description |
|---|---|---|
| Subtitles | Off | Download and embed subtitles |
| Subtitle languages | en,en-US |
Comma-separated ISO language codes |
| Thumbnail | On | Embed video thumbnail |
| Metadata | On | Embed title, artist, date metadata |
| Chapters | On | Embed chapter markers |
| SponsorBlock | Off | Remove sponsor/self-promo/interaction segments |
| Setting | Default | Description |
|---|---|---|
| Proxy | None | SOCKS5 or HTTP proxy URL (e.g. socks5://127.0.0.1:1080) |
| Speed limit | 0 (unlimited) | Maximum download speed in bytes/sec |
| Socket timeout | 30s | Connection timeout |
| Cookies file | None | Path to cookies.txt for authenticated downloads |
| Setting | Default | Description |
|---|---|---|
| Concurrent downloads | 2 | Simultaneous downloads (1–5) |
| Concurrent fragments | 4 | Parallel fragment downloads per video (1–8) |
| Max retries | 10 | Download retry attempts |
| Fragment retries | 10 | Per-fragment retry count |
| HTTP chunk size | 10 MB | Download chunk size |
| Buffer size | 128 KB | Stream buffer size |
| Setting | Default | Description |
|---|---|---|
| Windows-safe filenames | On | Replace characters invalid on Windows |
| Restrict filenames | Off | Limit filenames to ASCII characters only |
| Overwrite existing | Off | Whether to overwrite existing files |
┌──────────────────────────────────────────────────────────┐
│ App (CTk window) │
│ Main controller: tab wiring, event routing, lifecycle │
├──────────┬──────────┬──────────────┬─────────────────────┤
│ Download │ Queue │ History │ Settings │
│ Tab │ Tab │ Tab │ Tab │
│ URL, │ active, │ search, │ 25+ options, │
│ quality,│ retry, │ re-download,│ theme, proxy, │
│ format, │ cancel, │ copy URL, │ cookies, reset, │
│ options │ folder │ export │ update yt-dlp │
├──────────┴──────────┴──────────────┴─────────────────────┤
│ DownloadEngine │
│ Semaphore concurrency · Multi-strategy retry │
│ Progress hooks · Post-processor hooks │
│ _YtdlpLogger (error capture) · Thread-safe callbacks │
├──────────────────────────────────────────────────────────┤
│ yt-dlp + FFmpeg │
│ Extraction · Download · Merge · Transcode │
└──────────────────────────────────────────────────────────┘
YouTubeDownloaderPro/
├── youtube_downloader.py # Entry point — dependency check, then launch
├── pyproject.toml # PEP 621 packaging metadata
├── requirements.txt # pip dependencies
├── README.md # This file
├── LICENSE # MIT License
└── ytdlp_gui/ # Main package (11 modules)
├── __init__.py # Package version + public API exports
├── __main__.py # python -m ytdlp_gui support
├── models.py # Dataclasses: DownloadTask, VideoInfo
│ # Enums: DownloadStatus, QualityPreset,
│ # OutputFormat, AudioCodec
├── config.py # SettingsManager, AppSettings (dataclass),
│ # load_history(), save_history()
├── utils.py # URL validation (15+ patterns), formatting,
│ # disk checks, FFmpeg detection, open_folder()
├── engine.py # DownloadEngine — core download logic:
│ # QualityPresets, _YtdlpLogger,
│ # fallback strategies, progress hooks
├── app.py # App (CTk) — window shell, tab wiring,
│ # engine callbacks, lifecycle management
├── download_tab.py # Download configuration UI
├── queue_tab.py # Queue management UI
├── history_tab.py # History viewer UI
└── settings_tab.py # Settings UI — 25+ preferences
| Decision | Rationale |
|---|---|
Thread-safe callbacks via CTk.after(0, ...) |
All engine callbacks marshal updates to the main thread, preventing Tcl/Tk threading violations |
threading.Semaphore for concurrency |
Lightweight concurrency control without thread pool overhead; easily configurable (1–5) |
threading.Event for cancellation |
Each task gets an Event; the progress hook checks it and raises DownloadError to cleanly abort yt-dlp |
ignoreerrors: True + _YtdlpLogger |
Non-critical errors (subtitles, thumbnails) are silently skipped while fatal errors (private, deleted) are still detected and reported |
| Preset applied before format override | Fallback format strategies inherit format_sort and codec preferences from the active quality preset |
| Partial success detection | Playlist downloads where some items fail are treated as successful if at least one file was saved |
| Debounced history search (250ms) | Avoids recreating hundreds of widgets on every keystroke |
| Python dataclasses for models | Clean, typed data structures with no external dependency |
python youtube_downloader.pypython -m ytdlp_guipip install -e .
ytdlp-guiUse PyInstaller to create a distributable binary:
pip install pyinstaller
# Windows
pyinstaller --onefile --windowed --name "YouTubeDownloaderPro" youtube_downloader.py
# macOS / Linux
pyinstaller --onefile --windowed --name "YouTubeDownloaderPro" youtube_downloader.pyThe executable is created in dist/. Add --icon=icon.ico (Windows) or --icon=icon.icns (macOS) for a custom icon.
pip install build
python -m buildCreates wheel (.whl) and source distribution (.tar.gz) in dist/ for upload to PyPI or private registries.
| Problem | Solution |
|---|---|
| FFmpeg not found | Install FFmpeg and add its bin directory to your system PATH. Restart the application. |
| Subtitle download fails (HTTP 429) | The video still downloads — subtitles are gracefully skipped. Try again later, or reduce concurrent requests. |
| HTTP 403 errors | The engine retries with up to 4 fallback strategies. If all fail, try a fresh cookies.txt from your browser. |
| HTTP 429 (rate limited) | Reduce concurrent downloads and fragments in Settings. The engine retries automatically. |
| "Video unavailable" | The video is private, deleted, or geo-blocked. Try a VPN/proxy. This is a non-retryable error. |
| Slow downloads | Increase concurrent fragments (Settings → Performance). Check your network connection. |
| No subtitles found | Not all videos have subtitles. Add auto to subtitle languages for auto-generated ones. |
| Audio not extracted | Select the Audio Only quality preset and choose your codec (MP3, FLAC, etc.). |
| Age-restricted video | Export browser cookies and set the path in Settings → Cookies file. |
| yt-dlp out of date | Click Update yt-dlp in Settings, or run pip install -U yt-dlp. |
| App won't start | Verify Python 3.10+: python --version. Reinstall deps: pip install -r requirements.txt. |
| Settings corrupted | Delete ~/.ytdlp_gui/settings.json — the app recreates defaults on next launch. |
| Download stuck at 0% | Check internet connection. If using a proxy, verify reachability. Try concurrent downloads = 1. |
| Merged file is corrupt | Update FFmpeg to the latest version. Ensure enough disk space for temporary files. |
| yt-dlp JS runtime warning | Install Deno for full YouTube extraction support, or ignore — the fallback API works. |
Planned features for future releases:
- Batch URL import from text file
- Download scheduler (time-based queuing)
- Bandwidth usage statistics and graphs
- Custom yt-dlp argument passthrough
- Drag-and-drop URL support
- System tray minimization with completion notifications
- Auto-update check for new application versions
- Export queue as shareable configuration
- Format preview with file size estimation before download
- Multi-language UI localization
This tool is intended for personal, educational, and lawful purposes only. Users are responsible for complying with YouTube's Terms of Service, applicable copyright laws, and any other relevant regulations. The authors do not endorse or encourage the unauthorized downloading of copyrighted content.
This project is licensed under the MIT License. See LICENSE for the full text.
Copyright © 2026 Adarsh Pandey