Innovation Labs
YouTube Media Hub
A personal YouTube media hub that does far more than just download things.
Overview
YTDL started as a simple yt-dlp wrapper and grew into a full personal media hub. Dark-themed desktop GUI for Windows. Download videos, subscribe to channels, manage a library, queue scheduled downloads, track history — all from one place.
It runs minimised to the system tray and checks subscribed channels in the background. New content appears in a Watch Feed automatically. The library scanner finds everything you've downloaded and lets you play it directly from the app.
Built for one person. Shaped by how that person actually uses YouTube.
What It Does
.nfo + thumbnail + metadata sidecarsTech Stack
Architecture
The App class inherits from five tab mixins — each one contributing a full page of UI and event handlers while all state lives on a single object. Shared palette constants and helpers come from tabs/common.py.
All heavy work runs on daemon threads and marshals back to the tkinter main thread via self.after(0, callback). The download queue has a persistent worker thread and a scheduler thread. The watchlist manager runs a background loop that wakes hourly and spawns per-channel check threads on demand.
SQLite runs in WAL mode with a module-level threading lock. Every download gets a .nfo, a sidecar thumbnail, and a .info.json dropped alongside the file.
ytdl/
ytdl.py ← entry point
splash.py ← animated splash
gui.py ← App class
downloader.py ← DownloadQueue
watchlist.py ← WatchlistManager
library.py ← MediaItem + scanner
player.py ← AudioPlayer
videoplayer.py ← VideoPlayerWindow
history.py ← history wrapper
settings.py ← Settings class
db.py ← SQLite schema + CRUD
notifier.py ← desktop notifications
tray.py ← system tray
tabs/
watch_tab.py
queue_tab.py
history_tab.py
library_tab.py
settings_tab.py
Known Limitations
Screenshots