This commit is contained in:
Marek
2026-04-05 14:54:10 +02:00
parent 7d66746969
commit 6bbadb69c7
11 changed files with 129 additions and 147 deletions

View File

@@ -17,36 +17,43 @@ Drei Komponenten:
### Browser Extension (`browser_extension/`)
- **Manifest V2**, Firefox-kompatibel (`browser.*` API)
- `content.js` — extrahiert Videodaten direkt aus dem YouTube-DOM:
- `yt-lockup-view-model` (Homepage, Abos, Kanalseiten)
- `ytd-rich-item-renderer` (Homepage, Abos, Kanalseiten)
- `ytd-video-renderer` (Suchergebnisse)
- Debounced MutationObserver (250ms) fuer dynamisch geladene Cards
- IntersectionObserver (threshold 50%) — nur sichtbare Cards erfassen
- MutationObserver registriert neue Cards beim IntersectionObserver
- `yt-navigate-finish` Event-Listener fuer SPA-Navigation
- Deduplizierung ueber `sentUrls` Set
- `background.js` — empfaengt Nachrichten vom Content Script, sendet POST an Server
- Deduplizierung ueber `sentUrls` Set, wird bei Navigation geleert
- Batch-Versand: sammelt sichtbare Videos, sendet als Array
- Selektoren ohne Klassen: nur Tags (`h3`, `img`) und Attribute (`href`, `src`)
- `background.js` — empfaengt Batch vom Content Script, sendet POST an Server
- Laden via `about:debugging#/runtime/this-firefox` → "Temporaeres Add-on laden" → `manifest.json`
### Server (`backend/`)
- **Python, FastAPI, SQLAlchemy, SQLite** (`videos/youtubeapp.db`)
- **yt-dlp + ffmpeg** fuer Video-Download
- **yt-dlp + ffmpeg** fuer Video-Download und Live-Streaming
- Dockerisiert: `docker compose up --build -d` im `backend/` Verzeichnis
- Laeuft auf `http://localhost:8000`
- Download-Service speichert Videos unter `/videos/{id}.mp4`
- Beim Streamen wird automatisch heruntergeladen falls noetig
- Streaming: heruntergeladene Videos von Datei, sonst Live-Stream via yt-dlp + ffmpeg (fragmentiertes MP4)
- Dedup: beim Batch-Import wird bestehender Eintrag mit gleicher Video-ID geloescht und neu eingefuegt
- Sortierung: nach ID absteigend (erstes Video im Batch bekommt hoechste ID)
### App (`app/`)
- **Kotlin, Jetpack Compose**, Android/Android TV
- Gradle-Projekt, Modul `frontend`
- Aktueller Stand: Skeleton (nur `MainActivity` mit Platzhalter-Text)
- Geplante Screens: AllVideos, Downloaded, VideoDetail, VideoPlayer
- Screens: AllVideos (Grid), Downloaded, VideoDetail, VideoPlayer
- Retrofit fuer API-Calls, Coil fuer Thumbnails, ExoPlayer fuer Streaming
- Navigation mit Bottom Bar, Dark Theme
- Server-IP konfigurierbar in `ApiClient.kt` (aktuell `192.168.178.92`)
- Emulator: Android Studio → Device Manager → Pixel 6a, API 35
## API Endpoints
- `POST /videos` — Videodaten von Extension empfangen
- `GET /videos` — alle Videos abrufen
- `POST /videos` — Video-Batch von Extension empfangen (Liste von Videos, Dedup + Reverse-Insert)
- `GET /videos` — alle Videos abrufen (sortiert nach ID absteigend)
- `GET /videos/downloaded` — heruntergeladene Videos abrufen
- `POST /videos/{id}/download` — Download auf Server triggern
- `GET /videos/{id}/stream` — Video streamen
- `GET /videos/{id}/stream` — Video streamen (von Datei oder Live via yt-dlp/ffmpeg)
- `GET /videos/{id}/file` — Video-Datei zum Download auf Client ausliefern
## Projektstruktur
@@ -59,19 +66,28 @@ backend/
schemas.py — Pydantic Schemas (VideoCreate, VideoResponse)
routes/videos.py — Alle API-Routen
services/
video_service.py — CRUD-Operationen
download_service.py — yt-dlp Download-Logik
video_service.py — CRUD-Operationen, Dedup
download_service.py — yt-dlp Download + Live-Streaming
Dockerfile — Python 3.12 + ffmpeg
docker-compose.yml — Service-Definition, Port 8000, Volume /videos
.dockerignore — videos/, __pycache__/
.gitignore — videos/, __pycache__/
browser_extension/
manifest.json — Manifest V2, Permissions fuer youtube.com + localhost
content.js — DOM-basierte Video-Extraktion + MutationObserver
background.js — POST an Server
content.js — DOM-Extraktion + IntersectionObserver + Batch-Versand
background.js — Batch-POST an Server
app/
.gitignore — .gradle/, build/, .idea/, local.properties
frontend/src/main/java/com/youtubeapp/
MainActivity.kt — Einstiegspunkt (noch Skeleton)
MainActivity.kt — Einstiegspunkt
data/ — Video, ApiClient, VideoApi, VideoRepository
ui/screens/ — AllVideos, Downloaded, VideoDetail, VideoPlayer
ui/components/ — VideoCard
ui/viewmodel/ — VideoViewModel
ui/navigation/ — AppNavigation, Routes
ui/theme/ — Theme (Dark)
```
## Entscheidungen
@@ -81,4 +97,6 @@ app/
- Keine Benutzerprofile im Prototyp
- Videos werden auf dem Server gespeichert, Client speichert nur bei explizitem Download
- DOM-Extraktion statt ytInitialData-Parsing — funktioniert auch bei SPA-Navigation und Scrollen
- IntersectionObserver statt blindem Scan — nur sichtbare Videos erfassen
- Live-Streaming via yt-dlp/ffmpeg statt synchronem Download vor dem Streamen
- Sprache der Dokumentation: Deutsch