# FlightTube A desktop app that merges all your YouTube subscriptions into one newest-first feed, downloads the videos you pick, and — when you have no connection — shows only what you already downloaded. Built for the flight. Tauri 2 · Rust · React · Tailwind CSS 4 · SQLite ## How it works **Subscriptions come from Google Takeout, not the API.** Export *YouTube subscriptions* from [Takeout](https://takeout.google.com/) and import the `subscriptions.csv` in Settings. No OAuth, no API key, no Google Cloud project, nothing secret on disk. **Video metadata comes from YouTube's public Atom feed** — one request per channel to `youtube.com/feeds/videos.xml?channel_id=…`, fetched 8 at a time and merged into a single feed sorted by publish date. Thumbnails are mirrored to local disk so the feed still renders with no network. **Downloads shell out to `yt-dlp`,** pinned to H.264 video + AAC audio in an MP4 container. That caps quality at 1080p — YouTube only serves H.264 that high, and anything above it is VP9 or AV1, which the app's own player cannot reliably decode. The tradeoff is deliberate: every download is guaranteed to play inside FlightTube. ## Requirements ```bash brew install yt-dlp ffmpeg ``` Both are checked at startup; Settings shows their versions and this command if either is missing. `ffmpeg` is required because best-quality H.264 and AAC arrive as separate streams that must be merged. ## Running it ```bash npm install && npm run tauri dev ``` Build a real app bundle: ```bash npm run tauri build ``` ## Using it 1. **Settings → Import subscriptions.csv** — point it at your Takeout export. 2. **Refresh** — pulls the latest videos from every channel. 3. **Download** on any video — progress shows live on the button; click again to cancel. 4. Click a **downloaded** video to play it in the app. Click an undownloaded one to open it on YouTube. 5. **Offline** — the app detects a lost connection and collapses the feed to your downloads. The connectivity pill also toggles a forced offline mode for testing. Videos land in `~/Movies/FlightTube` (changeable in Settings). ## Limitations - The Atom feed returns only the **~15 most recent videos per channel**. There is no backfill and no pagination — this is a rolling recent window, not an archive. - Quality tops out at 1080p, by the deliberate choice described above. - `yt-dlp` needs occasional updating (`brew upgrade yt-dlp`) as YouTube changes. - Downloading videos is contrary to YouTube's Terms of Service. ## Tests ```bash cd src-tauri && cargo test ``` 37 unit tests cover the three places malformed input actually bites: Takeout CSV parsing, Atom feed parsing (against a captured real response), and `yt-dlp` progress-line parsing — plus the database rule that a refresh must never clobber download state. Two network-dependent tests are excluded by default: ```bash cargo test --test pipeline -- --ignored --nocapture # full pipeline vs. live feeds cargo test --test seed_real_db -- --ignored --nocapture # populate the installed app's db ``` ## Layout ``` src-tauri/src/ takeout.rs subscriptions.csv -> channels (pure, tested) feed.rs Atom XML -> videos, plus fetching (parse is pure, tested) downloader.rs yt-dlp arguments and progress lines (pure, tested) db.rs schema and every SQL statement thumbs.rs local thumbnail cache net.rs reachability probe commands.rs Tauri command surface — delegates only src/ components/ Sidebar, TopBar, VideoRow, DownloadButton, Player, Settings hooks/ useFeed, useDownloads, useConnectivity ``` Design notes and the implementation plan are in `docs/superpowers/`.