ki-video PLAN.md: Mixed Media Strategie — Stock-Fotos, echte Karten, Daten-Charts neben KI-Bildern, 4 CPU-Module, Szenentyp-Routing, DB-Schema erweitert
This commit is contained in:
parent
2394700d22
commit
41591a006a
1 changed files with 207 additions and 47 deletions
254
ki-video/PLAN.md
254
ki-video/PLAN.md
|
|
@ -16,14 +16,16 @@ Referenz-Stil: **"Geld & Imperien"** / **"Money & People"** (YouTube)
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Typ** | Commentary, Erklaervideo, Analyse |
|
| **Typ** | Commentary, Erklaervideo, Analyse |
|
||||||
| **Laenge** | 10-30 Minuten |
|
| **Laenge** | 10-30 Minuten |
|
||||||
| **Visuell** | Bilder + Karten + Infografiken + Text-Overlays + Ken-Burns |
|
| **Visuell** | Mixed Media: KI-Bilder + Stock-Fotos + echte Karten + Daten-Charts + Text-Overlays + Ken-Burns |
|
||||||
| **Stimme** | XTTS v2, natuerliche deutsche Maennerstimme, Voice-Cloning |
|
| **Stimme** | XTTS v2, natuerliche deutsche Maennerstimme, Voice-Cloning |
|
||||||
| **Untertitel** | Automatisch (faster-whisper → SRT) |
|
| **Untertitel** | Automatisch (faster-whisper → SRT) |
|
||||||
| **Avatar** | **Nein.** Erst ab v1.5 als optionaler PiP-Test. |
|
| **Avatar** | **Nein.** Erst ab v1.5 als optionaler PiP-Test. |
|
||||||
| **Kein** | Face-Cam, Realfilm, Vollbild-Avatar, Piper TTS |
|
| **Kein** | Face-Cam, Realfilm, Vollbild-Avatar, Piper TTS |
|
||||||
|
|
||||||
Das fertige Video besteht aus: Bilder mit Ken-Burns-Effekten + Voiceover + Hintergrundmusik
|
Das fertige Video besteht aus: Mixed Media (KI-Bilder + Stock-Fotos + Karten + Charts) mit
|
||||||
+ Text-Overlays + eingebrannte Untertitel. Das reicht. Die Referenz-Kanaele machen es genauso.
|
Ken-Burns-Effekten + Voiceover + Hintergrundmusik + Text-Overlays + eingebrannte Untertitel.
|
||||||
|
Entscheidend: KI-Bilder nur dort wo sie stark sind (Symbolik, Stimmung, Thumbnails).
|
||||||
|
Reale Fotos, Karten und Diagramme dort wo Fakten gezeigt werden.
|
||||||
|
|
||||||
### Anatomie eines 20-Min-Videos
|
### Anatomie eines 20-Min-Videos
|
||||||
|
|
||||||
|
|
@ -31,13 +33,19 @@ Das fertige Video besteht aus: Bilder mit Ken-Burns-Effekten + Voiceover + Hinte
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Skript** | ~3500-5000 Woerter | GPT-5.4 (Cloud) + menschliches Review |
|
| **Skript** | ~3500-5000 Woerter | GPT-5.4 (Cloud) + menschliches Review |
|
||||||
| **Szenenplan** | ~100 Szenen (JSON) | Qwen 14B (lokal) |
|
| **Szenenplan** | ~100 Szenen (JSON) | Qwen 14B (lokal) |
|
||||||
| **Hero-Bilder** | 10-15 Stueck | FLUX.1-dev (3090) |
|
| **Hero-Bilder** | 10-15 Stueck | FLUX.1-dev (3090), fuer Thumbnails + Kapitelwechsel |
|
||||||
| **Standard-Bilder** | 70-100 Stueck | SDXL (3x 3080) |
|
| **Konzept-Bilder** | 30-40 Stueck | SDXL (3080), symbolisch/abstrakt wo KI stark ist |
|
||||||
|
| **Stock-Fotos** | 20-30 Stueck | Pexels/Pixabay API (CPU), reale Orte/Personen/Ereignisse |
|
||||||
|
| **Karten** | 5-10 Stueck | MapLibre/OSM (CPU), echte Geografie statt KI-Karten |
|
||||||
|
| **Daten-Charts** | 5-10 Stueck | matplotlib (CPU), Oelpreis/BIP/Inflation aus echten Daten |
|
||||||
| **Voiceover** | 20 Min WAV | XTTS v2 (3080) |
|
| **Voiceover** | 20 Min WAV | XTTS v2 (3080) |
|
||||||
| **Untertitel** | SRT-Datei | faster-whisper (3080) |
|
| **Untertitel** | SRT-Datei | faster-whisper (3080) |
|
||||||
| **Hintergrundmusik** | 1-2 Tracks | Lizenzfrei, manuell gewaehlt |
|
| **Hintergrundmusik** | 1-2 Tracks | Lizenzfrei, manuell gewaehlt |
|
||||||
| **Text-Overlays** | 20-40 Stueck | FFmpeg (aus Szenenplan) |
|
| **Text-Overlays** | 20-40 Stueck | FFmpeg (aus Szenenplan) |
|
||||||
|
|
||||||
|
Bildmix-Logik: Der Szenenplan bestimmt pro Szene den Typ. Nicht alles KI-generiert.
|
||||||
|
KI fuer Stimmung/Symbolik, Stock fuer Realitaet, Karten fuer Geografie, Charts fuer Daten.
|
||||||
|
|
||||||
## v1 — Produktions-Pipeline
|
## v1 — Produktions-Pipeline
|
||||||
|
|
||||||
### Prinzip
|
### Prinzip
|
||||||
|
|
@ -48,7 +56,7 @@ GPT-5.4 (Cloud) → Qwen 14B (lokal) → 5 GPUs parallel → FFmpeg →
|
||||||
```
|
```
|
||||||
|
|
||||||
Kein Avatar. Kein dynamisches Scheduling. Kein Service-Mesh.
|
Kein Avatar. Kein dynamisches Scheduling. Kein Service-Mesh.
|
||||||
5 GPUs, feste Zuordnung, SQLite als Zustand, Python als Orchestrator.
|
5 GPUs feste Zuordnung + CPU-Module (Stock/Chart/Map), SQLite als Zustand, Python als Orchestrator.
|
||||||
|
|
||||||
### Pipeline-Schritte
|
### Pipeline-Schritte
|
||||||
|
|
||||||
|
|
@ -66,16 +74,17 @@ Mensch reviewt, korrigiert, gibt frei (~20 Min)
|
||||||
▼
|
▼
|
||||||
Qwen 14B (vLLM, :8401) → Szenenplan (JSON):
|
Qwen 14B (vLLM, :8401) → Szenenplan (JSON):
|
||||||
100 Szenen mit je:
|
100 Szenen mit je:
|
||||||
- Bildprompt (EN, fuer FLUX oder SDXL)
|
- Szenentyp: hero | concept | stock | map | chart | person
|
||||||
- Szenentyp: hero | standard | karte | infografik
|
- Bildprompt (EN, fuer hero/concept) ODER Suchbegriff (fuer stock/person)
|
||||||
|
ODER Geodaten (fuer map) ODER Datenquelle+Range (fuer chart)
|
||||||
- Text-Overlay (oder null)
|
- Text-Overlay (oder null)
|
||||||
- Dauer in Sekunden
|
- Dauer in Sekunden
|
||||||
│
|
│
|
||||||
▼
|
▼
|
||||||
Orchestrator uebernimmt
|
Orchestrator uebernimmt
|
||||||
|
|
||||||
PHASE 2 — PARALLEL-PRODUKTION (alle 5 GPUs, ~20 Min)
|
PHASE 2 — PARALLEL-PRODUKTION (GPUs + CPU, ~15-20 Min)
|
||||||
═════════════════════════════════════════════════════
|
══════════════════════════════════════════════════════
|
||||||
|
|
||||||
┌──────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────┐
|
||||||
│ ORCHESTRATOR (ki-tower, Python) │
|
│ ORCHESTRATOR (ki-tower, Python) │
|
||||||
|
|
@ -88,16 +97,29 @@ PHASE 2 — PARALLEL-PRODUKTION (alle 5 GPUs, ~20 Min)
|
||||||
│ ki-tower ││ Worker ││ Worker ││ Worker │
|
│ ki-tower ││ Worker ││ Worker ││ Worker │
|
||||||
│ ││ ││ ││ │
|
│ ││ ││ ││ │
|
||||||
│ FLUX.1 ││ XTTS v2 ││ SDXL ││ SDXL │ Whisper │
|
│ FLUX.1 ││ XTTS v2 ││ SDXL ││ SDXL │ Whisper │
|
||||||
│ Hero- ││ Voice ││ Standard ││ Standard│ + ESRGAN │
|
│ Hero- ││ Voice ││ Konzept- ││ Konzept-│ + ESRGAN │
|
||||||
│ Bilder ││ → SDXL ││ Bilder ││ Bilder │ Untertit. │
|
│ Bilder ││ → SDXL ││ Bilder ││ Bilder │ Untertit. │
|
||||||
│ 10-15 St ││ → Rest ││ ~40 Stk ││ ~40 Stk │ + Upscale │
|
│ 10-15 St ││ → Rest ││ ~20 Stk ││ ~20 Stk │ + Upscale │
|
||||||
│ ~10 Min ││ ~20 Min ││ ~20 Min ││ ~20 Min │ ~5 Min │
|
│ ~10 Min ││ ~15 Min ││ ~10 Min ││ ~10 Min │ ~5 Min │
|
||||||
└──────────┘└──────────┘└──────────┘└──────────────────────┘
|
└──────────┘└──────────┘└──────────┘└──────────────────────┘
|
||||||
|
|
||||||
Alle GPUs starten SOFORT. Keine Abhaengigkeitskette.
|
┌──────────────────────────────────────────────────────────┐
|
||||||
3080 #0: XTTS v2 Voiceover (~15 Min), danach SDXL Restbilder (~5 Min).
|
│ CPU-PARALLEL (ki-tower, laueft gleichzeitig mit GPUs) │
|
||||||
|
│ │
|
||||||
|
│ Stock-Fetcher → Pexels/Pixabay API → 20-30 Fotos ~30s │
|
||||||
|
│ Chart-Gen → matplotlib/plotly → 5-10 Charts ~10s │
|
||||||
|
│ Map-Renderer → MapLibre/OSM → 5-10 Karten ~30s │
|
||||||
|
│ Person-Fetcher → Wikimedia Commons → Portraits ~10s │
|
||||||
|
│ │
|
||||||
|
│ Gesamt CPU-Media: <60 Sekunden (parallel zu GPU-Jobs) │
|
||||||
|
└──────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
Alle GPUs + CPU starten SOFORT. Keine Abhaengigkeitskette.
|
||||||
|
3080 #0: XTTS v2 Voiceover (~15 Min), danach SDXL Restbilder.
|
||||||
3080 #3: Whisper (braucht Audio, wartet auf #0) + ESRGAN parallel.
|
3080 #3: Whisper (braucht Audio, wartet auf #0) + ESRGAN parallel.
|
||||||
Engpass = Bildgenerierung (~20 Min fuer ~100 Bilder auf 3+1 GPUs).
|
CPU-Module brauchen <60 Sek und sind fertig bevor die erste GPU-Szene steht.
|
||||||
|
Engpass = XTTS v2 Voiceover (~15 Min). Bildgenerierung ist jetzt schneller
|
||||||
|
weil nur noch ~50 KI-Bilder statt ~100 (Rest = Stock/Karten/Charts).
|
||||||
|
|
||||||
PHASE 3 — ASSEMBLY (ki-tower, ~10-15 Min)
|
PHASE 3 — ASSEMBLY (ki-tower, ~10-15 Min)
|
||||||
══════════════════════════════════════════
|
══════════════════════════════════════════
|
||||||
|
|
@ -111,28 +133,31 @@ Export: Thumbnail (FLUX hero-Bild) + Titel + Description + Tags
|
||||||
|
|
||||||
### Zeitschaetzung: 20-Min-Video (ohne Avatar)
|
### Zeitschaetzung: 20-Min-Video (ohne Avatar)
|
||||||
|
|
||||||
| Phase | Dauer | GPUs | Engpass |
|
| Phase | Dauer | GPUs/CPU | Engpass |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 1. Skript + Szenenplan | ~30 Min | 1 (3090) + Cloud | Mensch (Review) |
|
| 1. Skript + Szenenplan | ~30 Min | 1 (3090) + Cloud | Mensch (Review) |
|
||||||
| 2. Parallel-Produktion | ~20 Min | 5 (alle) | Bildgenerierung |
|
| 2. Parallel-Produktion | ~15 Min | 5 GPUs + CPU | XTTS v2 Voiceover |
|
||||||
| 3. Assembly | ~10 Min | 1 (3090 NVENC) | FFmpeg Compositing |
|
| 3. Assembly | ~10 Min | 1 (3090 NVENC) | FFmpeg Compositing |
|
||||||
| **Gesamt (Maschine)** | **~30 Min** | | |
|
| **Gesamt (Maschine)** | **~25 Min** | | |
|
||||||
| **Gesamt (inkl. Mensch)** | **~60 Min** | | |
|
| **Gesamt (inkl. Mensch)** | **~55 Min** | | |
|
||||||
|
|
||||||
Ohne Avatar: kein SadTalker-Engpass, keine TTS→Avatar-Abhaengigkeit.
|
Mixed Media verschiebt den Engpass: Statt ~100 KI-Bilder auf GPU nur noch ~50.
|
||||||
Bildgenerierung ist der Engpass, aber auf 4 GPUs verteilt (3x SDXL + 1x FLUX).
|
CPU-Module (Stock/Karten/Charts) liefern den Rest in <60 Sekunden.
|
||||||
|
Neuer Engpass = XTTS v2 (~15 Min fuer 20 Min Audio), nicht mehr Bildgenerierung.
|
||||||
|
|
||||||
### GPU-Zuordnung v1
|
### GPU-Zuordnung v1
|
||||||
|
|
||||||
| GPU | Aufgabe | VRAM | Dauer | Output |
|
| GPU | Aufgabe | VRAM | Dauer | Output |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| **3090** | Qwen 14B (Szenenplan) → FLUX.1-dev (Hero-Bilder) | 12 GB | ~10 Min | 10-15 hochwertige Key-Visuals |
|
| **3090** | Qwen 14B (Szenenplan) → FLUX.1-dev (Hero-Bilder) | 12 GB | ~10 Min | 10-15 hochwertige Key-Visuals |
|
||||||
| **3080 #0** | XTTS v2 (Voiceover) → SDXL (Restbilder) | 4→7 GB | ~20 Min | 20 Min Audio + ~15 Bilder |
|
| **3080 #0** | XTTS v2 (Voiceover) → SDXL (Restbilder) | 4→7 GB | ~15 Min | 20 Min Audio + ~10 Bilder |
|
||||||
| **3080 #1** | SDXL (Standard-Szenen, durchgehend) | 7 GB | ~20 Min | ~40 Bilder |
|
| **3080 #1** | SDXL (Konzept-Szenen) | 7 GB | ~10 Min | ~20 Bilder |
|
||||||
| **3080 #2** | SDXL (Standard-Szenen, durchgehend) | 7 GB | ~20 Min | ~40 Bilder |
|
| **3080 #2** | SDXL (Konzept-Szenen) | 7 GB | ~10 Min | ~20 Bilder |
|
||||||
| **3080 #3** | faster-whisper (Untertitel) + Real-ESRGAN (Upscaling) | 3 GB | ~5 Min | SRT + upscaled Thumbnails |
|
| **3080 #3** | faster-whisper (Untertitel) + Real-ESRGAN (Upscaling) | 3 GB | ~5 Min | SRT + upscaled Thumbnails |
|
||||||
|
| **CPU** | Stock-Fetcher + Chart-Gen + Map-Renderer + Person-Fetcher | 0 | <1 Min | 30-50 Medien-Dateien |
|
||||||
|
|
||||||
Alle 4 Bild-GPUs zusammen: **~100 Bilder in ~20 Minuten.**
|
KI-Bilder: **~50 Stueck in ~10-15 Minuten** (3x SDXL + 1x FLUX).
|
||||||
|
CPU-Medien: **~50 Stueck in <60 Sekunden** (Stock/Karten/Charts, parallel).
|
||||||
3080 #3 ist nach ~5 Min fertig und idle — kann bei Bedarf auch SDXL uebernehmen.
|
3080 #3 ist nach ~5 Min fertig und idle — kann bei Bedarf auch SDXL uebernehmen.
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
|
|
@ -233,8 +258,10 @@ CREATE TABLE scenes (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
video_id INTEGER REFERENCES videos(id),
|
video_id INTEGER REFERENCES videos(id),
|
||||||
scene_nr INTEGER NOT NULL,
|
scene_nr INTEGER NOT NULL,
|
||||||
scene_type TEXT NOT NULL, -- hero | standard | karte | infografik
|
scene_type TEXT NOT NULL, -- hero | concept | stock | map | chart | person
|
||||||
prompt TEXT NOT NULL,
|
prompt TEXT, -- Bildprompt (hero/concept) oder null
|
||||||
|
query TEXT, -- Suchbegriff (stock/person) oder null
|
||||||
|
data_source TEXT, -- Datenquelle (chart) oder Geodaten (map) oder null
|
||||||
overlay TEXT,
|
overlay TEXT,
|
||||||
duration_s REAL NOT NULL,
|
duration_s REAL NOT NULL,
|
||||||
image_path TEXT,
|
image_path TEXT,
|
||||||
|
|
@ -245,6 +272,7 @@ CREATE TABLE jobs (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
video_id INTEGER REFERENCES videos(id),
|
video_id INTEGER REFERENCES videos(id),
|
||||||
job_type TEXT NOT NULL, -- tts | sdxl | flux | whisper | esrgan | assembly
|
job_type TEXT NOT NULL, -- tts | sdxl | flux | whisper | esrgan | assembly
|
||||||
|
-- | stock_fetch | chart_gen | map_render | person_fetch
|
||||||
gpu TEXT,
|
gpu TEXT,
|
||||||
status TEXT DEFAULT 'queued', -- queued→running→done→failed
|
status TEXT DEFAULT 'queued', -- queued→running→done→failed
|
||||||
input_data TEXT,
|
input_data TEXT,
|
||||||
|
|
@ -269,7 +297,13 @@ CREATE TABLE jobs (
|
||||||
│ └── 2026-03-16-iran-hyperschall/
|
│ └── 2026-03-16-iran-hyperschall/
|
||||||
│ ├── script.md
|
│ ├── script.md
|
||||||
│ ├── scenes.json
|
│ ├── scenes.json
|
||||||
│ ├── images/ # 80-120 generierte Bilder
|
│ ├── images/
|
||||||
|
│ │ ├── hero/ # FLUX Hero-Bilder (10-15)
|
||||||
|
│ │ ├── concept/ # SDXL Konzept-Bilder (30-40)
|
||||||
|
│ │ ├── stock/ # Pexels/Pixabay Fotos (20-30)
|
||||||
|
│ │ ├── map/ # MapLibre/OSM Karten (5-10)
|
||||||
|
│ │ ├── chart/ # matplotlib Charts (5-10)
|
||||||
|
│ │ └── person/ # Wikimedia Portraits
|
||||||
│ ├── audio/
|
│ ├── audio/
|
||||||
│ │ ├── voiceover.wav
|
│ │ ├── voiceover.wav
|
||||||
│ │ └── music.mp3
|
│ │ └── music.mp3
|
||||||
|
|
@ -300,14 +334,20 @@ published : YouTube-Upload
|
||||||
```
|
```
|
||||||
Alle 10 Sekunden:
|
Alle 10 Sekunden:
|
||||||
1. videos WHERE status = 'scenes'
|
1. videos WHERE status = 'scenes'
|
||||||
→ Jobs erstellen: 1x TTS, Nx SDXL, Mx FLUX, 1x Whisper, 1x ESRGAN
|
→ Jobs erstellen nach Szenentyp:
|
||||||
|
hero/concept → GPU-Jobs (FLUX/SDXL)
|
||||||
|
stock/person → CPU-Jobs (stock_fetch/person_fetch)
|
||||||
|
map → CPU-Jobs (map_render)
|
||||||
|
chart → CPU-Jobs (chart_gen)
|
||||||
|
+ 1x TTS, 1x Whisper, 1x ESRGAN
|
||||||
|
|
||||||
2. jobs WHERE status = 'queued'
|
2. jobs WHERE status = 'queued'
|
||||||
→ Abhaengigkeiten pruefen (Whisper wartet auf TTS)
|
→ GPU-Jobs: Abhaengigkeiten pruefen → An Worker senden (HTTP REST)
|
||||||
→ An Worker senden (HTTP REST)
|
→ CPU-Jobs: Sofort lokal ausfuehren (Stock/Chart/Map-Module)
|
||||||
|
|
||||||
3. jobs WHERE status = 'running'
|
3. jobs WHERE status = 'running'
|
||||||
→ Worker pollen, Status updaten
|
→ GPU-Worker pollen, Status updaten
|
||||||
|
→ CPU-Jobs sind synchron, Status sofort done/failed
|
||||||
|
|
||||||
4. Alle Jobs eines Videos done?
|
4. Alle Jobs eines Videos done?
|
||||||
→ Assembly-Job starten (FFmpeg)
|
→ Assembly-Job starten (FFmpeg)
|
||||||
|
|
@ -344,6 +384,94 @@ ki-tower (3090) gpu-worker (4x 3080)
|
||||||
└─────────────────────────┘ └──────────────────────────────┘
|
└─────────────────────────┘ └──────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Media-Module (CPU, ki-tower)
|
||||||
|
|
||||||
|
Vier Python-Module die der Orchestrator lokal ausfuehrt. Kein GPU, kein externer Service.
|
||||||
|
Laufen parallel zu GPU-Jobs, brauchen <60 Sekunden fuer alle Szenen zusammen.
|
||||||
|
|
||||||
|
### Stock-Fetcher (~50 Zeilen)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Pexels API (kostenlos, 200 Requests/Std)
|
||||||
|
def fetch_stock(query: str, output_path: str) -> str:
|
||||||
|
resp = requests.get("https://api.pexels.com/v1/search",
|
||||||
|
params={"query": query, "per_page": 3, "orientation": "landscape"},
|
||||||
|
headers={"Authorization": PEXELS_KEY})
|
||||||
|
url = resp.json()["photos"][0]["src"]["large2x"] # 1920px
|
||||||
|
download(url, output_path)
|
||||||
|
return output_path
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Fallback**: Pixabay API (ebenfalls kostenlos) wenn Pexels kein Ergebnis
|
||||||
|
- **Bildgroesse**: 1920x1280 (wird per ffmpeg auf 1920x1080 zugeschnitten)
|
||||||
|
- **Lizenz**: Pexels-Lizenz erlaubt kommerzielle Nutzung ohne Attribution
|
||||||
|
|
||||||
|
### Chart-Generator (~80 Zeilen)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# matplotlib + yfinance/FRED fuer echte Wirtschaftsdaten
|
||||||
|
def generate_chart(data_source: str, date_range: str, title: str, output_path: str) -> str:
|
||||||
|
data = fetch_data(data_source, date_range)
|
||||||
|
fig, ax = plt.subplots(figsize=(19.2, 10.8), dpi=100)
|
||||||
|
ax.plot(data.index, data.values, color="#e63946", linewidth=2.5)
|
||||||
|
ax.set_title(title, fontsize=32, fontweight="bold", color="white")
|
||||||
|
fig.patch.set_facecolor("#1a1a2e")
|
||||||
|
ax.set_facecolor("#1a1a2e")
|
||||||
|
fig.savefig(output_path, dpi=100, bbox_inches="tight")
|
||||||
|
return output_path
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Datenquellen**: yfinance (Aktien, Oel, Gold), FRED API (BIP, Inflation), World Bank
|
||||||
|
- **Stil**: Dunkler Hintergrund, passend zum Video-Look (konfigurierbar pro Kanal)
|
||||||
|
- **Output**: 1920x1080 PNG, direkt als Szene verwendbar
|
||||||
|
|
||||||
|
### Map-Renderer (~60 Zeilen)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Statische Karte via Mapbox Static API (kostenlos bis 50k/Monat)
|
||||||
|
def render_map(center: list, zoom: int, markers: list, style: str, output_path: str) -> str:
|
||||||
|
marker_str = ",".join([f"pin-s+e63946({m['lon']},{m['lat']})" for m in markers])
|
||||||
|
url = (f"https://api.mapbox.com/styles/v1/mapbox/{style}/static/"
|
||||||
|
f"{marker_str}/{center[0]},{center[1]},{zoom}/1920x1080@2x"
|
||||||
|
f"?access_token={MAPBOX_TOKEN}")
|
||||||
|
download(url, output_path)
|
||||||
|
return output_path
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Stile**: `dark-v11` (Standard), `satellite-v9` (Satellit), `light-v11` (hell)
|
||||||
|
- **Marker**: Rote Pins mit Labels fuer Staedte, Militaerbasen, Routen
|
||||||
|
- **Alternative**: OpenStreetMap + Leaflet-Screenshot (komplett kostenlos, etwas aufwaendiger)
|
||||||
|
|
||||||
|
### Person-Fetcher (~40 Zeilen)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Wikimedia Commons API fuer Portraits realer Personen
|
||||||
|
def fetch_person(name: str, output_path: str) -> str:
|
||||||
|
resp = requests.get("https://en.wikipedia.org/api/rest_v1/page/summary/" +
|
||||||
|
name.replace(" ", "_"))
|
||||||
|
image_url = resp.json().get("originalimage", {}).get("source")
|
||||||
|
if image_url:
|
||||||
|
download(image_url, output_path)
|
||||||
|
return output_path
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Quelle**: Wikipedia/Wikimedia (CC-lizenziert, Attribution noetig)
|
||||||
|
- **Fallback**: Pexels-Suche nach Name wenn kein Wikipedia-Bild
|
||||||
|
- **Hinweis**: Nur fuer oeffentliche Personen (Politiker, CEOs). Keine Privatpersonen.
|
||||||
|
|
||||||
|
### Szenentyp-Routing im Orchestrator
|
||||||
|
|
||||||
|
```python
|
||||||
|
SCENE_HANDLERS = {
|
||||||
|
"hero": lambda s: submit_gpu_job("flux", s), # 3090
|
||||||
|
"concept": lambda s: submit_gpu_job("sdxl", s), # 3080 #1/#2
|
||||||
|
"stock": lambda s: fetch_stock(s["query"], ...), # CPU, <2 Sek
|
||||||
|
"map": lambda s: render_map(s["data_source"],...),# CPU, <3 Sek
|
||||||
|
"chart": lambda s: generate_chart(s["data_source"],...), # CPU, <1 Sek
|
||||||
|
"person": lambda s: fetch_person(s["query"], ...), # CPU, <2 Sek
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Konkretes Beispiel: "Irans Hyperschall-Schlag" (24 Min)
|
## Konkretes Beispiel: "Irans Hyperschall-Schlag" (24 Min)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -354,14 +482,26 @@ INPUT:
|
||||||
PHASE 1 (~30 Min):
|
PHASE 1 (~30 Min):
|
||||||
GPT-5.4 → Skript (4500 Woerter)
|
GPT-5.4 → Skript (4500 Woerter)
|
||||||
Mensch reviewt (~20 Min)
|
Mensch reviewt (~20 Min)
|
||||||
Qwen 14B → Szenenplan: 105 Szenen (JSON)
|
Qwen 14B → Szenenplan: 105 Szenen (JSON), davon:
|
||||||
|
12x hero — dramatische Key-Visuals, Thumbnail
|
||||||
|
35x concept — symbolische Szenen (Rakete, Explosion, Diplomatie)
|
||||||
|
25x stock — echte Fotos (Khamenei, Pentagon, Oeltanker, Staedte)
|
||||||
|
8x map — Strait of Hormuz, Flugbahnen, Militaerbasen
|
||||||
|
5x chart — Oelpreis, Ruestungsausgaben, Handelsvolumen
|
||||||
|
20x person — Politiker, Militaerfuehrer, Analysten
|
||||||
|
|
||||||
PHASE 2 (~20 Min, alle 5 GPUs parallel):
|
PHASE 2 (~15 Min, 5 GPUs + CPU parallel):
|
||||||
3090: 12 Hero-Bilder (FLUX.1-dev)
|
GPU:
|
||||||
3080 #0: XTTS v2 → 24 Min Voiceover → danach 15 SDXL-Bilder
|
3090: 12 Hero-Bilder (FLUX.1-dev) ~10 Min
|
||||||
3080 #1: 40 Standardbilder (SDXL)
|
3080 #0: XTTS v2 → 24 Min Voiceover → danach 10 SDXL ~15 Min
|
||||||
3080 #2: 40 Standardbilder (SDXL)
|
3080 #1: 18 Konzept-Bilder (SDXL) ~10 Min
|
||||||
3080 #3: Whisper → Untertitel-SRT + ESRGAN Upscaling
|
3080 #2: 17 Konzept-Bilder (SDXL) ~10 Min
|
||||||
|
3080 #3: Whisper → Untertitel-SRT + ESRGAN ~5 Min
|
||||||
|
CPU (parallel, <60 Sek):
|
||||||
|
Stock-Fetcher: 25 Fotos von Pexels
|
||||||
|
Person-Fetcher: 20 Portraits von Wikipedia
|
||||||
|
Map-Renderer: 8 Karten von Mapbox
|
||||||
|
Chart-Generator: 5 Charts (Oelpreis via yfinance, etc.)
|
||||||
|
|
||||||
PHASE 3 (~10 Min):
|
PHASE 3 (~10 Min):
|
||||||
FFmpeg: 105 Szenen × Ken-Burns → Videospur
|
FFmpeg: 105 Szenen × Ken-Burns → Videospur
|
||||||
|
|
@ -369,8 +509,15 @@ PHASE 3 (~10 Min):
|
||||||
FFmpeg: Text-Overlays + Untertitel
|
FFmpeg: Text-Overlays + Untertitel
|
||||||
NVENC: H.265 → final.mp4 (1080p)
|
NVENC: H.265 → final.mp4 (1080p)
|
||||||
|
|
||||||
Gesamtzeit Maschine: ~30 Min
|
Gesamtzeit Maschine: ~25 Min
|
||||||
Gesamtzeit inkl. Mensch: ~60 Min
|
Gesamtzeit inkl. Mensch: ~55 Min
|
||||||
|
|
||||||
|
Bildmix im fertigen Video:
|
||||||
|
~45% KI-generiert (hero + concept) → Stimmung, Symbolik
|
||||||
|
~25% Stock-Fotos → Realitaet, Glaubwuerdigkeit
|
||||||
|
~20% Portraits → Personen, Gesichter
|
||||||
|
~8% Karten → Geografie, Routen
|
||||||
|
~5% Charts → Daten, Fakten
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nicht-Ziele (v1)
|
## Nicht-Ziele (v1)
|
||||||
|
|
@ -383,6 +530,8 @@ Gesamtzeit inkl. Mensch: ~60 Min
|
||||||
- Keine YouTube-Upload-Automation
|
- Keine YouTube-Upload-Automation
|
||||||
- Keine Batch-Produktion (ein Video nach dem anderen)
|
- Keine Batch-Produktion (ein Video nach dem anderen)
|
||||||
- Kein Kubernetes, kein Service-Mesh, kein Proxmox
|
- Kein Kubernetes, kein Service-Mesh, kein Proxmox
|
||||||
|
- Keine eigene Bild-Datenbank (Stock wird live per API geholt)
|
||||||
|
- Kein CLIP-Scoring (kommt spaeter fuer automatische Bildauswahl)
|
||||||
|
|
||||||
## Umsetzungsreihenfolge
|
## Umsetzungsreihenfolge
|
||||||
|
|
||||||
|
|
@ -393,11 +542,13 @@ PHASE 1 — ki-tower Grundinstallation (Woche 1-2)
|
||||||
├── GPT-5.4 API anbinden → erster Skript-Test
|
├── GPT-5.4 API anbinden → erster Skript-Test
|
||||||
└── Ergebnis: "Skript + Szenenplan funktionieren"
|
└── Ergebnis: "Skript + Szenenplan funktionieren"
|
||||||
|
|
||||||
PHASE 2 — Bildgenerierung (Woche 3-4)
|
PHASE 2 — Bildgenerierung + Media-Module (Woche 3-4)
|
||||||
├── ComfyUI + FLUX.1-dev in Docker → Hero-Bilder testen
|
├── ComfyUI + FLUX.1-dev in Docker → Hero-Bilder testen
|
||||||
├── SDXL in Docker (gleicher ComfyUI oder A1111)
|
├── SDXL in Docker (gleicher ComfyUI oder A1111)
|
||||||
├── Workflow: Szenenplan-JSON → Bildprompts → Bilder
|
├── Media-Module: Stock-Fetcher, Chart-Gen, Map-Renderer, Person-Fetcher
|
||||||
└── Ergebnis: "100 Bilder in <30 Min generiert"
|
├── Pexels API-Key + Mapbox Token einrichten (beides kostenlos)
|
||||||
|
├── Szenentyp-Routing: hero/concept → GPU, stock/map/chart/person → CPU
|
||||||
|
└── Ergebnis: "Mixed Media (50 KI + 50 Stock/Charts/Karten) in <15 Min"
|
||||||
|
|
||||||
PHASE 3 — 3080-Rig parallel aufbauen (Woche 3-5)
|
PHASE 3 — 3080-Rig parallel aufbauen (Woche 3-5)
|
||||||
├── Debian 12 + CUDA + Docker (identischer Stack)
|
├── Debian 12 + CUDA + Docker (identischer Stack)
|
||||||
|
|
@ -485,7 +636,8 @@ Nicht in der Planung. Entscheidung nach 3 Monaten v1:
|
||||||
| Skript-LLM | **GPT-5.4** (Cloud) | Kreativitaet > lokale Inferenz. ~0.50 EUR/Skript. |
|
| Skript-LLM | **GPT-5.4** (Cloud) | Kreativitaet > lokale Inferenz. ~0.50 EUR/Skript. |
|
||||||
| Szenenplan-LLM | **Qwen 14B** (lokal) | Strukturiertes JSON, keine Kreativitaet noetig |
|
| Szenenplan-LLM | **Qwen 14B** (lokal) | Strukturiertes JSON, keine Kreativitaet noetig |
|
||||||
| Hero-Bilder | **FLUX.1-dev** (3090) | Beste Qualitaet fuer Thumbnails, Titel, Kapitelwechsel |
|
| Hero-Bilder | **FLUX.1-dev** (3090) | Beste Qualitaet fuer Thumbnails, Titel, Kapitelwechsel |
|
||||||
| Standard-Bilder | **SDXL** (3x 3080) | Schnell, gut genug, massiv parallelisierbar |
|
| Konzept-Bilder | **SDXL** (3x 3080) | Symbolik, Stimmung — dort wo KI stark ist |
|
||||||
|
| Reale Medien | **Stock + Karten + Charts** (CPU) | Fakten, Personen, Geografie — dort wo KI schwach ist |
|
||||||
| Stimme (v1) | **XTTS v2** (3080 #0) | Voice-Cloning, natuerlich, deutsch. Keine Uebergangsloesung. |
|
| Stimme (v1) | **XTTS v2** (3080 #0) | Voice-Cloning, natuerlich, deutsch. Keine Uebergangsloesung. |
|
||||||
| Untertitel | **faster-whisper** (3080 #3) | CUDA-nativ, schnell |
|
| Untertitel | **faster-whisper** (3080 #3) | CUDA-nativ, schnell |
|
||||||
| Avatar (v1) | **Nein** | Fragil, Qualitaetsrisiko, unnoetige Komplexitaet |
|
| Avatar (v1) | **Nein** | Fragil, Qualitaetsrisiko, unnoetige Komplexitaet |
|
||||||
|
|
@ -502,8 +654,10 @@ Nicht in der Planung. Entscheidung nach 3 Monaten v1:
|
||||||
| 1 | **XTTS v2 deutsche Stimme klingt unnatuerlich** | Hoch | Voice-Cloning mit guter Referenz. Fallback: OpenAI TTS als Bruecke (~0.50 EUR/Video). |
|
| 1 | **XTTS v2 deutsche Stimme klingt unnatuerlich** | Hoch | Voice-Cloning mit guter Referenz. Fallback: OpenAI TTS als Bruecke (~0.50 EUR/Video). |
|
||||||
| 2 | **VRAM-Tetris auf 3090** (Qwen + FLUX) | Mittel | Sequentiell, nicht parallel. vLLM Model-Unloading. 14B statt 32B. |
|
| 2 | **VRAM-Tetris auf 3090** (Qwen + FLUX) | Mittel | Sequentiell, nicht parallel. vLLM Model-Unloading. 14B statt 32B. |
|
||||||
| 3 | **Pipeline wird zu komplex vor erstem Video** | Hoch | Erste 3 Videos manuell (Bash-Scripts). Orchestrator erst in Phase 6. |
|
| 3 | **Pipeline wird zu komplex vor erstem Video** | Hoch | Erste 3 Videos manuell (Bash-Scripts). Orchestrator erst in Phase 6. |
|
||||||
| 4 | **SDXL-Bilder stilistisch inkonsistent** | Mittel | Feste Negativprompts + Style-Presets pro Kanal. Seed-Listen. |
|
| 4 | **SDXL-Bilder stilistisch inkonsistent** | Niedrig | Weniger KI-Bilder (~50 statt ~100). Feste Style-Presets + Negativprompts. |
|
||||||
| 5 | **FFmpeg-Assembly hat Artefakte** | Mittel | Ken-Burns-Presets manuell testen. Ueberblendungen standardisieren. |
|
| 5 | **FFmpeg-Assembly hat Artefakte** | Mittel | Ken-Burns-Presets manuell testen. Ueberblendungen standardisieren. |
|
||||||
|
| 6 | **Stock-API liefert unpassende Bilder** | Niedrig | 3 Ergebnisse abrufen, bestes per CLIP-Score auswaehlen. Fallback: SDXL-Concept. |
|
||||||
|
| 7 | **Pexels/Mapbox API-Limits** | Niedrig | Pexels: 200 Req/Std (reicht fuer ~6 Videos/Std). Mapbox: 50k/Monat. Weit ueber Bedarf. |
|
||||||
|
|
||||||
## Kosten
|
## Kosten
|
||||||
|
|
||||||
|
|
@ -513,4 +667,10 @@ Nicht in der Planung. Entscheidung nach 3 Monaten v1:
|
||||||
| Strom gpu-worker (bei Bedarf) | ~10-30 EUR |
|
| Strom gpu-worker (bei Bedarf) | ~10-30 EUR |
|
||||||
| GPT-5.4 API (Skripte) | ~3-15 EUR |
|
| GPT-5.4 API (Skripte) | ~3-15 EUR |
|
||||||
| Cloud-TTS Fallback | ~0-10 EUR |
|
| Cloud-TTS Fallback | ~0-10 EUR |
|
||||||
|
| Pexels API | kostenlos |
|
||||||
|
| Mapbox API | kostenlos (bis 50k Req/Monat) |
|
||||||
|
| yfinance/FRED | kostenlos |
|
||||||
| **Gesamt** | **~45-85 EUR** |
|
| **Gesamt** | **~45-85 EUR** |
|
||||||
|
|
||||||
|
Keine zusaetzlichen Kosten durch Mixed Media. Alle APIs haben kostenlose Tiers
|
||||||
|
die fuer die geplante Produktionsmenge (8-12 Videos/Monat) weit ausreichen.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue