Bug fixes - Desktop auto-rescan: snapshot was_running before check_notifications updates prev_job_states, so the post-download rescan actually fires. - web::run shutdown: replace `let _ = tx;` (which dropped the sender immediately and short-circuited the shutdown select!) with std::mem::forget(tx); add an idle fallback so the `-> !` is honored. - /api/preview now resolves the bundled yt-dlp path and extends PATH for deno discovery, matching the rest of the downloader. - Scheduler interval clamped to >=1h on read so a manually-edited config.toml with 0 hours can't trigger every tick. - maintenance::is_within canonicalizes the parent + filename when the target is missing; remove_files treats NotFound as success. Security - Session tokens stored with issued-at Instant and pruned past 30 day TTL on every touch (was: unbounded HashSet). - Login rate-limited per source IP: 5 failures → 60s lockout (429). - Secure cookie flag added when X-Forwarded-Proto: https is present. - 4 MiB body size cap via DefaultBodyLimit. - Security headers middleware: CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy. - JS safeUrl() defangs javascript:/vbscript:/data:text URLs before interpolation into src= attributes. - Bundled yt-dlp install verifies SHA-256 against the release's SHA2-256SUMS; deno hash printed for visual inspection. Install also reports byte counts every 3s so users see live progress. - yt-offline.db chmod 0600 at open time on Unix. New features - Bundled yt-dlp + deno mode: settings toggle (System/Bundled) plus one-click Install/Update from settings. Ensures executable bit on every launch in case the install chmod was missed. - Download queue with configurable max_concurrent (1–10); pending jobs surfaced in both UIs. - Music download mode: --extract-audio into music/<artist>/, separate sidebar entry, /api/music + /music-files/ endpoints, inline <audio>. - Download quality selector: Best / 1080p / 720p / 480p / 360p. - Sort videos by Newest / Oldest (upload_date from info.json with release_date fallback). - Plex metadata: per-episode .nfo (title, season/episode, aired, runtime, plot from .description), <stem>-thumb.jpg symlink, and show-level tvshow.nfo. - yt-dlp retry/throttle defaults: --retries 30 --fragment-retries 30 --retry-sleep linear=1:30:2 --sleep-requests 1 to ride out the "Connection reset by peer" failures. Performance - password_required cached in AtomicBool; refreshed only on password change. Eliminates a SQLite query per static-file fetch. - Job::log → VecDeque for O(1) front-pop instead of O(n) drain. - Library scan parallelized across cores via stdlib parallel_map. - Web UI poll: 600ms while active, 5s when idle, 2s after errors. - Music scan now recursive (Artist/Album/Track.opus). - percent_encode_segment uses write! to avoid per-byte String allocs. Code quality - 27 unit tests covering parse_progress, parse_stem, extract_after, detect_url_kind, srt_to_vtt, count_cookies, percent_encode_segment, bind_mode_of, hash_password, lang_label, is_within, sanitize, year_of, aired_date, xml_escape. - Unified library::find_video + Channel::all_videos() iterator, replacing three duplicated linear searches. - Downloader::browser wired to --cookies-from-browser as a fallback when no cookies.txt is present. - mpv detection now matches the binary basename, not substring. - Settings modal scroll fix; web settings expose all new fields. 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.