# yt-dlf — Handoff > Übergabedokument für die Fortsetzung in einer Claude-Code-Session. > Stand: 2026-08-29 — App läuft produktiv auf Gisela unter > http://172.30.1.11:3300 (nur internes Netz), Downloads nach > `/home/stwaidele/YouTube//`. Neu: Whisper-Transkriptions-Fallback > für Videos ohne Untertitel, live verifiziert (archive.org en + Instagram > de, RTX 3080). > Dauerhafte Fakten stehen in `README.md`/`INSTALL.md`; hier steht nur, was > **nicht** aus Code und Git-Historie ersichtlich ist. **🔜 NÄCHSTE SESSION:** Kein konkreter inhaltlicher Auftrag hinterlegt. Arbeitskopie auf Gisela: `/home/stwaidele/Claude/yt-dlp` (Verzeichnisname ≠ Repo-Name `yt-dlf`!). ## Offene Punkte - [ ] `users.txt` auf Gisela anlegen, falls Login gewünscht (`python3 scripts/add_user.py `, danach `systemctl --user restart yt-dlf`); ohne Login zeigen `ads-*.html` Platzhalter-Werbung. - [ ] Leeres Repo `stwaidele/yt-dlp` auf Gitea existiert neben `yt-dlf` — Stefan entscheidet: löschen oder Projekt dorthin umziehen. - [ ] Mac-Instanz: ob die App auf dem Mac weiterlaufen soll, ist offen; die dortigen gitignorten Dateien (`users.txt`, `ads-*.html`-Anpassungen) wurden nicht nach Gisela übernommen. - [x] Deploy-Status klären (erledigt 29.08. — läuft jetzt auf Gisela, siehe Session-Block) ## Stolperfallen - **Port 3000 ist auf Gisela belegt** (Open-WebUI bindet `172.30.1.11:3000`) — yt-dlf läuft deshalb auf **3300**. Bei Port-Änderungen zuerst `ss -tlnp` prüfen. - **Git-Konten-Mix (nur Mac)** — auf dem Mac zeigt `origin` direkt auf `git@gitea.101010.cloud:stwaidele/yt-dlf.git` mit dem alten generischen `claude`-Key; dort Claude-Commits per Author-Override und Push über den Modell-Alias. Auf **Gisela** ist das gelöst: Clone über `git@gitea-fable-5:stwaidele/yt-dlf.git`, Repo-Config steht auf `Claude Fable 5` / `fable-5@waidele.info`. - **Rollende Auto-Captions** — YouTube-Auto-Untertitel wiederholen in jedem Cue die letzte Zeile des Vorgänger-Cues; kurze Fortsetzungen (einzelne Wörter) tragen dabei **keine** Inline-Timing-Tags. Ein Filter rein über Timing-Tags reicht deshalb nicht — der Parser verwirft stattdessen führende Wiederholungszeilen (`src/lib/subtitle.js`, `scripts/subtitle_to_markdown.py`, beide identisch halten!). ## Session 2026-08-29 — Whisper-Fallback für Videos ohne Untertitel (Claude Fable 5) Auftrag: Plattformen ohne Untertitel (Instagram & Co.) sollen trotzdem Transkripte liefern. Umsetzung: `scripts/transcribe.py` (faster-whisper, `large-v3-turbo`, CUDA mit CPU-Fallback) + Hook in `src/routes/api/download/+server.js` — springt nur an, wenn der Download keine `.vtt`/`.srt` hinterlässt; die VTT läuft danach durch die normale MD-Konvertierung. venv liegt in `.venv/` (gitignored, Python 3.13, **nicht** das Linuxbrew-Python 3.14 — dafür gab es keine ctranslate2-Wheels). cuDNN/cuBLAS kommen aus pip und werden im Script per `ctypes.CDLL(RTLD_GLOBAL)` vorgeladen, damit kein `LD_LIBRARY_PATH` in der systemd-Unit nötig ist. Modell-Cache: `~/.cache/huggingface` (~1,6 GB, bereits geladen). Live verifiziert: archive.org „Duck and Cover" (E2E über die API, Fallback sprang an, Transkript einwandfrei) und Direktlauf auf GPU (`cuda`, Spracherkennung en p=1.00). Testerkenntnis: **Vimeo verlangt inzwischen Login** und taugt nicht mehr als Test-Plattform; archive.org funktioniert. Zusätzlich an einem echten Instagram-Video verifiziert (`~/YouTube/Video by sugarkane2003/`, ~3 min, Deutsch automatisch erkannt, Transkript inhaltlich einwandfrei — typische Whisper-Schwächen nur bei Namen/Anglizismen wie „Wheel" statt „Reel"); lief als Direktaufruf der beiden Fallback-Schritte, weil der Download vor dem Feature lag und die Original-URL nicht gespeichert ist. Nebenwirkung des GPU-Direkttests: `~/YouTube/Me at the zoo/Me at the zoo.en.vtt` ist jetzt die Whisper-Version statt der YouTube-Caption (im echten Betrieb kein Thema, Fallback läuft nur ohne vorhandene Untertitel). ## Session 2026-08-29 — Deploy auf Gisela (Claude Fable 5) Auftrag: yt-dlf auf Gisela betreiben, Weboberfläche nur im WireGuard-/internen Netz, Downloads unter `/home/stwaidele/YouTube/`. Umsetzung: Build im Repo-Checkout (`npm install && npm run build`), systemd-**User**-Unit `~/.config/systemd/user/yt-dlf.service` (enabled, Linger war bereits aktiv → Autostart ohne Login). Die Unit setzt `HOST=172.30.1.11`, `PORT=3300`, `DOWNLOAD_DIR`, `YTDLP_PATH` (yt-dlp kommt aus Linuxbrew, nicht auf dem systemd-PATH). Gisela hat **kein eigenes wg-Interface** — sie hängt direkt im internen Netz `172.30.1.0/24`, in das die WireGuard-Peers geroutet werden; „nur WG-Netz" heißt hier also: exakt an die LAN-IP binden (localhost, Docker-Bridges und IPv6 nachweislich nicht erreichbar). Live verifiziert: Testdownload „Me at the zoo" über die API komplett durchgelaufen, Dateien inkl. deduplizierter MDs unter `~/YouTube/Me at the zoo/`. Nebenbei: `package-lock.json` durch npm auf Gisela normalisiert (nur `libc`-Felder entfernt, kein Versions-Update). ## Session 2026-08-29 — Untertitel-Dedup-Fix & Push nach Gitea (Claude Fable 5) Stefans Befund: MD-Dateien aus VTT-Untertiteln enthielten jeden Satz ~3×. Ursache waren die rollenden YouTube-Auto-Captions (Uploader-Untertitel waren nie betroffen — sie sind die bessere Quelle und werden von yt-dlp bereits bevorzugt geladen). Fix in beiden Parsern (JS + Python-CLI), dazu überspringt `src/routes/api/download/+server.js` jetzt inhaltsgleiche MD-Dateien (z.B. `en.md` ≡ `en-orig.md`). Erster Ansatz (nur getaggte Zeilen behalten) scheiterte am Randfall ungetaggter Einzelwort-Fortsetzungen → siehe Stolperfalle. Live verifiziert an realen Dateien unter `~/YouTube/*/`; alle 16 Bestands-MDs dort und in `~/Downloads/*/` mit dem CLI regeneriert. Repo erstmals seit Mai gepusht (main `6df26c1..a7d7d1c` über `gitea-fable-5`-Alias); Stefan verlagert die Weiterentwicklung auf Gisela. ## Session 2026-08-29 — Handoff angelegt (Claude Fable 5) Projekt hatte noch keine `Handoff.md`; per `/handoff init` aus README, INSTALL.md und Git-Historie erstellt. Kein Projekt-`CLAUDE.md` vorhanden. Beide bisherigen Commits (16.05.) stammen von Stefan; seither keine Änderungen im Working Tree. ## Typische Handgriffe Dev-Server, Deployment und User-Verwaltung sind vollständig in `README.md` und `INSTALL.md` dokumentiert — dort nachschlagen, hier nicht duplizieren. Betrieb auf Gisela (systemd-User-Dienst, läuft als `stwaidele`): ```bash systemctl --user status|restart|stop yt-dlf journalctl --user -u yt-dlf -f # Nach Code-Änderungen: npm run build && systemctl --user restart yt-dlf ``` ## Verwandte Handoffs _keine_