mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 19:44:12 +00:00
96 lines
2.9 KiB
Markdown
96 lines
2.9 KiB
Markdown
# YouTube Thumbnail Download — Design
|
|
|
|
**Datum:** 14.02.2026
|
|
**Status:** Approved
|
|
|
|
## Ziel
|
|
|
|
Automatischer Download von YouTube-Video-Thumbnails und Kanalbildern als Payload Media, damit diese offline verfügbar sind und von Payload's Sharp-Pipeline optimiert werden.
|
|
|
|
## Scope
|
|
|
|
- **Video-Thumbnails:** Auto-Download bei Sync + Bulk-Import für bestehende Einträge
|
|
- **Kanalbilder:** Profilbilder und Banner beim Channel-Sync
|
|
- **Nicht im Scope:** Kommentar-Autor-Avatare (bleiben als externe URLs)
|
|
|
|
## Qualität
|
|
|
|
- YouTube-Thumbnails: `hqdefault` (480x360)
|
|
- Payload generiert daraus automatisch alle responsive Sizes (thumbnail, small, medium, etc.)
|
|
|
|
## Architektur: Inline beim Sync
|
|
|
|
Download direkt im Sync-Flow integriert, kein separater Queue-Job.
|
|
|
|
### 1. Kern-Utility: `downloadAndUploadImage()`
|
|
|
|
**Datei:** `src/lib/utils/media-download.ts`
|
|
|
|
```typescript
|
|
interface DownloadOptions {
|
|
url: string
|
|
filename: string
|
|
alt?: string
|
|
tenantId?: number
|
|
}
|
|
|
|
async function downloadAndUploadImage(
|
|
payload: Payload,
|
|
options: DownloadOptions
|
|
): Promise<number | null>
|
|
```
|
|
|
|
- Lädt Bild von URL herunter
|
|
- Erstellt Payload Media-Dokument (mit Tenant-Zuordnung)
|
|
- Sharp-Pipeline generiert alle 11 responsive Sizes automatisch
|
|
- Duplikat-Erkennung: Prüft ob Media mit gleichem Dateinamen + Tenant existiert
|
|
- Fehler → `null` (kein harter Fehler, Sync läuft weiter)
|
|
|
|
### 2. Integration in YouTube-Sync
|
|
|
|
**YouTubeContent** (beim Erstellen/Updaten):
|
|
- Wenn `thumbnail`-Feld leer → Download von `https://img.youtube.com/vi/{videoId}/hqdefault.jpg`
|
|
- Media-ID in `thumbnail`-Feld speichern
|
|
- Manuell hochgeladene Thumbnails werden nie überschrieben
|
|
|
|
**YouTubeChannels** (beim Channel-Sync):
|
|
- Profilbild und Banner aus YouTube API herunterladen (falls Felder leer)
|
|
- In entsprechende Media-Felder speichern
|
|
|
|
### 3. Bulk-Import Endpoint
|
|
|
|
**Route:** `POST /api/youtube/thumbnails/bulk`
|
|
**Auth:** Super-Admin erforderlich
|
|
|
|
- Findet alle `YouTubeContent`-Einträge ohne Thumbnail
|
|
- Downloadet sequentiell mit 500ms Delay (Rate-Limit-Schutz)
|
|
- Response: `{ processed, downloaded, skipped, errors }`
|
|
- Optional: `?dryRun=true`
|
|
|
|
### 4. Fehlerbehandlung
|
|
|
|
| Aspekt | Verhalten |
|
|
|--------|-----------|
|
|
| Rate-Limiting | 500ms Delay zwischen Downloads (Bulk) |
|
|
| Timeout | 10s pro Download |
|
|
| Retry | Kein Retry (YouTube CDN zuverlässig) |
|
|
| 404/Fehler | `null` zurückgeben, Sync fortsetzen |
|
|
| Duplikate | Existierendes Media zurückgeben |
|
|
| Manuelle Uploads | Nie überschreiben |
|
|
| Logging | Console.log (nicht AuditLogs) |
|
|
|
|
## Betroffene Dateien
|
|
|
|
### Neu
|
|
- `src/lib/utils/media-download.ts` — Kern-Utility
|
|
- `src/app/(payload)/api/youtube/thumbnails/bulk/route.ts` — Bulk-Endpoint
|
|
|
|
### Modifiziert
|
|
- YouTube-Sync-Services — Thumbnail-Download nach Content-Erstellung
|
|
- YouTubeChannels-Sync — Kanalbild-Download nach Channel-Update
|
|
|
|
## Nicht-Ziele
|
|
|
|
- Keine Kommentar-Avatare herunterladen
|
|
- Kein Queue-basierter Download
|
|
- Keine automatische Aktualisierung bestehender Thumbnails
|