yt-dlp already speaks ~1,800 sites; the changes here teach the rest of the app to route them through platform-specific output folders and remember where each creator was downloaded from. New `platform` module - `Platform` enum: YouTube, TikTok, Twitch, Vimeo, Bandcamp, SoundCloud, Odysee, Other. - `classify_url` returns both the source platform and a `UrlKind` (Channel / Playlist / Video / Unknown) — per-platform path parsing for each supported host. - `platform_root(channels_root, platform)` returns the on-disk folder per platform. YouTube keeps the legacy `channels/` for backward compat; the others live as siblings (`tiktok/`, `twitch/`, …). - `write_source_url` / `read_source_url` persist the originating URL in a `.source-url` sidecar at each creator folder so re-checks no longer rely on the YouTube-only "UC + 22 chars" heuristic. Downloader - `Downloader::start` now takes `&UrlInfo` instead of `&UrlKind` and routes the yt-dlp `-o` template into the right platform folder. - For channel downloads it also writes `.source-url` so future re-checks recover the exact URL. - Output template uses `%(uploader,channel,creator|Unknown)s` so non-YouTube sites that don't expose `channel` still get a sensible creator folder. - Per-platform `archive.txt` keeps cross-platform IDs (TikTok numeric vs YouTube base64) from colliding. - New `recheck_url(&Channel)` prefers `source_url` and falls back to the legacy YouTube heuristic for libraries created before this change. Library scanner - `scan_channels` now walks every platform's folder and tags each `Channel` with its `platform` + `source_url`. Sort key puts the platform first, then name, so the sidebar groups cleanly. - `Channel` gains `platform: Platform` and `source_url: Option<String>` fields, populated from the on-disk sidecar. Web UI - `WebState` gains `library_root` (= parent of channels_root). The `/files/` ServeDir is mounted at library_root so non-YouTube videos resolve at `/files/<platform>/<creator>/<file>`. Existing YouTube URLs still work — they're now `/files/channels/...` instead of `/files/...` and the server-rendered JSON updates accordingly. - Maintenance scan + remove use `library_root` so non-YouTube content is included. - `ChannelInfo` JSON exposes `platform`, `platform_label`, `platform_icon`, and `source_url`. - Sidebar groups channels by platform with each platform's icon. - "Check for new videos" now uses the stored `source_url` (with the YouTube heuristic as a last-resort fallback). - Download dialog preview shows the detected source + destination folder. Desktop UI - App gains a `library_root` field mirroring the web side; maintenance ops scan/remove against it. - Sidebar channel labels are prefixed with the platform icon for non-YouTube channels; tooltip carries the platform name. - Download URL field surfaces both source platform and folder path preview as you type. Plex - Non-YouTube creators get their show folder prefixed with the platform name (e.g., `TikTok - cooluser`) so a YouTube channel and a TikTok account with the same name don't collide. Backward compatibility - Existing YouTube libraries (`channels/<handle>/...`) are untouched. New platform folders are created on first run as siblings. - Channels without a `.source-url` (i.e., everything that pre-dates this commit) fall through to the YouTube heuristic, preserving the existing re-check behavior. Tests - 14 new `platform` tests cover URL classification per platform, channel handle extraction, and `platform_root` layout. The old `detect_url_kind` / `extract_after` tests move into platform.rs since the canonical implementation lives there now. - 41 unit tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .vscode | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| icon.png | ||
| LICENSE | ||
| PKGBUILD | ||
| README.md | ||
| SECURITY_AUDIT.md | ||
| youtube-backup.desktop | ||
| yt-offline-0.1.0-1-x86_64.pkg.tar.zst | ||
yt-offline
A desktop app for archiving YouTube channels using yt-dlp. Browse your downloaded channels, manage downloads, and play videos — all from a native GUI.
Features
- Channel Browser — Browse downloaded channels and videos with thumbnails
- Smart Download Routing — Paste any YouTube URL; channels, playlists, and single videos are automatically routed to the right folder
- Playlist View — Channels with playlist subdirectories show them in the sidebar
- Themes — Dark, Light, Dracula, Trans, and three Emo/Scene themes
- Settings GUI — Configure everything from inside the app
- Video Playback — Launch videos in mpv, VLC, or any player
- Search — Filter across your entire library in real time
- System Tray — Minimize to tray
Building
Arch Linux / Manjaro
A PKGBUILD is included:
git clone https://codeberg.org/anassaeneroi/yt-offline
cd yt-offline
makepkg -si
Or build manually:
sudo pacman -S --needed rust yt-dlp mpv
cargo build --release
sudo install -Dm755 target/release/yt-offline /usr/bin/yt-offline
Debian / Ubuntu / Linux Mint
Install build dependencies:
sudo apt install \
build-essential pkg-config curl git \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev libssl-dev \
libgtk-3-dev libayatana-appindicator3-dev
Install Rust (if not already installed):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
Install runtime dependencies:
sudo apt install yt-dlp mpv
Build and install:
git clone https://codeberg.org/anassaeneroi/yt-offline
cd yt-offline
cargo build --release
sudo install -Dm755 target/release/yt-offline /usr/bin/yt-offline
cp youtube-backup.desktop ~/.local/share/applications/yt-offline.desktop
macOS
Install Xcode command line tools and Homebrew dependencies:
xcode-select --install
brew install yt-dlp mpv
Install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
Build:
git clone https://codeberg.org/anassaeneroi/yt-offline
cd yt-offline
cargo build --release
The binary is at target/release/yt-offline. Copy it wherever you like, or run it in place.
Windows
-
Install Rust — accept the default MSVC toolchain when prompted
-
Install Visual Studio Build Tools with the Desktop development with C++ workload
-
Install yt-dlp and mpv:
winget install yt-dlp.yt-dlp winget install mpv.net -
Clone and build:
git clone https://codeberg.org/anassaeneroi/yt-offline cd yt-offline cargo build --release
The binary is at target\release\yt-offline.exe. Copy it wherever you like and run it.
Note: The first build takes a while — Rust compiles all dependencies from scratch.
Configuration
On first run, create a config.toml next to the binary (or edit it from the Settings button inside the app):
[backup]
directory = "/path/to/your/video/library"
[player]
command = "mpv"
[ui]
theme = "dark"
Options
| Setting | Default | Description |
|---|---|---|
backup.directory |
./channels |
Where downloaded videos are stored |
player.command |
mpv |
Command used to launch the video player |
ui.theme |
dark |
dark, light, dracula, trans, emo-nocturnal, emo-coffin, emo-scene-queen |
Usage
-
Download a channel/video/playlist — click ⬇ Downloads, paste a YouTube URL. The app detects the URL type and routes it automatically:
- Channel URL →
channels/<handle>/ - Single video →
channels/<channel-name>/ - Playlist →
channels/<channel-name>/<playlist-name>/
- Channel URL →
-
Browse your library — channels appear in the left sidebar. If a channel has playlist subdirectories they show as collapsible sub-items.
-
Play a video — click ▶ Play on any video card, or double-click the thumbnail.
-
Change settings — click ⚙ Settings to change the backup directory, player, or theme without editing the file.
Troubleshooting
yt-dlp not found
Make sure it's installed and on your $PATH. On Windows, restart your terminal after install.
Build fails on Debian/Ubuntu with missing headers
Make sure you installed all packages in the build dependencies block above, especially libayatana-appindicator3-dev and libgtk-3-dev.
Build fails on Windows with linker errors Make sure Visual Studio Build Tools are installed with the C++ workload selected, not just the base tools.
Videos won't play
Check player.command in config.toml (or Settings). The command must accept a file path as its last argument.
Thumbnails not loading Supported formats: JPEG, PNG, WebP. Other formats are silently skipped.
Project Structure
src/
main.rs entry point
app.rs UI and main loop
downloader.rs yt-dlp integration and URL detection
library.rs channel/playlist/video scanner
config.rs config file loading and saving
theme.rs all colour themes
database.rs SQLite (reserved for future use)
tray.rs system tray
License
See LICENSE.