2026-10-10 16:50:54 +02:00
# youtube_rede_korrigieren
Korrigiert automatische Abschriften deutscher Reden (z. B. YouTube-Untertitel als
Text) mit einem lokalen Sprachmodell über Ollama: Rechtschreibung, Satzzeichen,
Hörfehler, Absätze – möglichst wortgetreu, ohne Zusammenfassung oder Glättung.
2026-10-10 19:51:32 +02:00
Die Werkzeuge sind einzeln oder hintereinander nutzbar:
2026-10-10 19:23:28 +02:00
| Skript | Aufgabe |
|---|---|
2026-10-10 19:51:32 +02:00
| `extract_text.py` | YouTube-URL → Textdatei in einem Schritt (die beiden folgenden zusammen) |
2026-10-10 19:23:28 +02:00
| `yt_untertitel.py` | Untertitel eines YouTube-Videos als VTT herunterladen |
| `vtt2txt.py` | VTT in eine Rohabschrift (Text) umwandeln |
| `rede_korrigieren.py` | Rohabschrift (oder VTT direkt) mit dem Sprachmodell korrigieren |
2026-10-10 16:50:54 +02:00
## Voraussetzungen
2026-10-10 18:19:14 +02:00
- Python 3.9+ (nur Standardbibliothek)
- für den Download: [yt-dlp ](https://github.com/yt-dlp/yt-dlp ) (`pip install yt-dlp` )
2026-10-10 16:50:54 +02:00
- Ollama auf `127.0.0.1:11434` mit dem Modell `qwen3:32b`
(`ollama pull qwen3:32b` )
Für gute Geschwindigkeit muss das Modell komplett in den Grafikspeicher passen.
Mit `OLLAMA_NUM_PARALLEL=1` braucht `qwen3:32b` bei 16k Kontext rund 24 GB
(eine RTX 3090). Bei `OLLAMA_NUM_PARALLEL=4` landet ein Drittel auf der CPU und
der Lauf wird etwa 12-mal langsamer.
## Aufruf
2026-10-10 19:51:32 +02:00
Von der YouTube-URL zum korrigierten Text:
```bash
./extract_text.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' -o lahnstein.txt
./rede_korrigieren.py -i lahnstein.txt # → lahnstein.korrigiert.txt
```
Dasselbe in Einzelschritten, wenn die VTT-Datei erhalten bleiben soll:
2026-10-10 18:19:14 +02:00
```bash
./yt_untertitel.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' -n Lahnstein -d testdaten
./vtt2txt.py -i testdaten/Lahnstein.de-orig.vtt
./rede_korrigieren.py -i testdaten/Lahnstein.de-orig.txt
```
2026-10-10 19:51:32 +02:00
Der Schritt über `vtt2txt.py` ist optional: `rede_korrigieren.py` nimmt auch die
`.vtt` direkt. Die `.txt` lohnt sich, um den Rohtext anzusehen oder ein Glossar
daraus zu erstellen.
### URL → Text in einem Schritt: `extract_text.py`
Lädt die Untertitel und speichert nur den Text; die VTT-Datei bleibt ein
Zwischenschritt im temporären Verzeichnis. Die Spurwahl ist dieselbe wie bei
`yt_untertitel.py` , nur ist die Standardsprache die des Original-Audios.
```bash
./extract_text.py -u 'https://www.youtube.com/watch?v=rm6lADgf6GQ' # → output.txt
./extract_text.py -u URL -l de -o testdaten/rede.txt # Sprache und Ziel
./rede_korrigieren.py -i output.txt # → output.korrigiert.txt
```
| Option | Bedeutung |
|---|---|
| `-u` , `--url` | YouTube-URL, Pflicht |
| `-l` , `--lang` | Sprache; Standard: Sprache des Original-Audios (`<sprache>-orig` ) |
| `-o` , `--output` | Ausgabedatei (Verzeichnisse werden angelegt, vorhandene Datei überschrieben); Standard: `output.txt` |
2026-10-10 19:23:28 +02:00
2026-10-10 18:19:14 +02:00
### Untertitel herunterladen: `yt_untertitel.py`
Lädt die Untertitel eines YouTube-Videos über `yt-dlp` als VTT-Datei, ohne das
Video selbst. Gewählt wird:
1. manuelle Untertitel in der gewünschten Sprache, sonst
2. automatische Untertitel in der Originalsprache des Videos (`de-orig` ).
Automatische Untertitel ohne `-orig` sind Maschinenübersetzungen aus einer anderen
Sprache und werden nie genommen. Gibt es keine passende Spur, nennt das Skript die
vorhandenen Sprachen.
```bash
./yt_untertitel.py -u URL # → <Video-ID>.de-orig.vtt
./yt_untertitel.py -u URL -n Lahnstein -d testdaten # → testdaten/Lahnstein.de-orig.vtt
```
| Option | Bedeutung |
|---|---|
| `-u` , `--url` | YouTube-URL, Pflicht |
| `-n` , `--name` | Dateiname ohne Endung; Standard: Video-ID |
| `-l` , `--lang` | Sprache; Standard: `de` |
| `-d` , `--dir` | Zielverzeichnis (wird angelegt); Standard: aktuelles Verzeichnis |
Eine vorhandene Datei gleichen Namens wird überschrieben.
2026-10-10 17:50:51 +02:00
### Untertitel umwandeln: `vtt2txt.py`
Macht aus VTT-Untertiteln (z. B. von `yt-dlp --write-auto-subs` ) die Rohabschrift
für `rede_korrigieren.py` : Zeitstempel und Tags werden entfernt. YouTube-Auto-Untertitel
zeigen ein rollendes Fenster, jeder Block wiederholt das Ende des vorigen. Übernommen
wird nur, was nach dieser Überlappung neu ist; sagt der Redner eine Zeile wirklich
zweimal, bleibt sie zweimal erhalten.
```bash
./vtt2txt.py -i rede.de.vtt # → rede.de.txt
./vtt2txt.py -i ramstein.de*.vtt # mehrere Dateien, je → *.txt
./vtt2txt.py -i "ramstein.de*.vtt" # Muster löst das Programm auf (Windows)
./vtt2txt.py -i rede.de.vtt -o out/rede.txt # eigene Ausgabedatei
./vtt2txt.py -i *.vtt -o out/ # alle in ein Verzeichnis
```
| Option | Bedeutung |
|---|---|
| `-i` , `--input` | eine oder mehrere VTT-Dateien oder Muster, Pflicht |
| `-o` , `--output` | Ausgabedatei (nur bei einer Eingabedatei) oder Verzeichnis (vorhanden oder mit `/` am Ende); Standard: `<Eingabe ohne Endung>.txt` neben der Eingabe |
Eine fehlerhafte Datei (keine Untertitel, nicht UTF-8) wird gemeldet, die übrigen
werden trotzdem umgewandelt; der Exit-Code ist dann 1.
### Abschrift korrigieren: `rede_korrigieren.py`
2026-10-10 16:50:54 +02:00
```bash
./rede_korrigieren.py -i rede.txt # → rede.korrigiert.txt
./rede_korrigieren.py -i rede.txt -o out/rede.txt # eigene Ausgabedatei
./rede_korrigieren.py -i rede.txt -g rede.glossar.txt # mit Glossar
2026-10-10 17:50:51 +02:00
./rede_korrigieren.py -i rede.de.vtt # VTT direkt → rede.de.korrigiert.txt
2026-10-10 16:50:54 +02:00
```
| Option | Bedeutung |
|---|---|
2026-10-10 17:50:51 +02:00
| `-i` , `--input` | Eingabedatei: Rohabschrift (`.txt` ) oder Untertitel (`.vtt` , wird wie mit `vtt2txt.py` umgewandelt), Pflicht |
2026-10-10 16:50:54 +02:00
| `-o` , `--output` | Ausgabedatei; Standard: `<Eingabe ohne Endung>.korrigiert.txt` neben der Eingabe |
| `-g` , `--glossar` | Glossar mit festen Ersetzungen und Schreibweisen |
## Ablauf
1. **Fließtext: ** Untertitel-Zeilenumbrüche werden entfernt.
2. **Feste Ersetzungen ** aus dem Glossar (`falsch => richtig` ) werden im Rohtext
angewendet, bevor das Modell ihn sieht.
3. **Korrektur: ** Der Text wird in Abschnitte von ca. 1200 Wörtern geteilt (immer
am Satzende) und abschnittsweise vom Modell korrigiert. Fortschritt wird live
angezeigt.
4. **Wortzahl-Prüfung: ** Weicht die Wortzahl eines Abschnitts um mehr als 5 % ab,
gibt es eine Warnung (mögliche Auslassungen oder Ergänzungen).
5. **Absätze: ** Das Modell nennt nur Satznummern, an denen ein Absatz beginnt; der
Text selbst wird dabei nicht verändert. Absätze über 10 Sätze werden nochmals
geteilt, Absätze unter 3 Sätzen mit dem Nachbarn verbunden.
Zweifelhafte Stellen markiert das Modell als `Lesart [prüfen: Originalwortlaut]` .
## Glossar
Eine Zeile pro Eintrag, `#` leitet Kommentare ein:
```text
# feste Ersetzung (ganze Wörter, Groß-/Kleinschreibung zählt, Reihenfolge = Datei)
Willly Brand => Willy Brandt
Kremmel => Kreml
2026-10-10 19:23:28 +02:00
# Hinweis fürs Modell (korrekte Schreibweise, optional mit Erläuterung)
2026-10-10 16:50:54 +02:00
Multi-Domain Task Force
2026-10-10 19:23:28 +02:00
Michael Gorbatschow (Vorname so belassen)
2026-10-10 16:50:54 +02:00
```
Ersetzungen ohne Treffer werden gemeldet (Tippfehler im Glossar).
2026-10-10 18:11:58 +02:00
`ramstein.glossar.txt` und `magdeburg.glossar.txt` sind Beispiele zu den Testdaten.
2026-10-10 16:50:54 +02:00
2026-10-10 16:54:00 +02:00
## Testdaten
2026-10-10 18:19:14 +02:00
`testdaten/` enthält drei Reden, jeweils als automatische YouTube-Untertitel
2026-10-10 17:52:56 +02:00
(`.vtt` , Original) und daraus mit `vtt2txt.py` gewonnener Rohtext (`.txt` , Eingabe
für das Programm):
2026-10-10 16:54:00 +02:00
2026-10-10 17:52:56 +02:00
- `ramstein.de.*` : Rede über die US Air Base Ramstein (mit Glossar `ramstein.glossar.txt` )
2026-10-10 18:11:58 +02:00
- `magdeburg.de-orig.*` : Rede in Magdeburg (mit Glossar `magdeburg.glossar.txt` )
2026-10-10 18:19:14 +02:00
- `Lahnstein.de-orig.*` : Rede „Respekt geht anders“ in Lahnstein (noch ohne Glossar,
geladen mit `yt_untertitel.py` )
2026-10-10 16:54:00 +02:00
```bash
2026-10-10 17:52:56 +02:00
./vtt2txt.py -i "testdaten/*.vtt" # erzeugt alle .txt neu
2026-10-10 16:54:00 +02:00
./rede_korrigieren.py -i testdaten/ramstein.de.txt -g ramstein.glossar.txt
# → testdaten/ramstein.de.korrigiert.txt (nicht versioniert)
```
Ein Lauf dauert mit `qwen3:32b` vollständig auf einer RTX 3090 etwa 6 Minuten.
2026-10-10 16:57:37 +02:00
## Tests
```bash
python3 -m pytest
```
Die Tests brauchen kein Ollama: Modellaufrufe werden durch Fakes ersetzt. Geprüft
2026-10-10 18:11:58 +02:00
werden Abschnittsbildung, Glossar (inkl. „jede Ersetzung in den Beispiel-Glossaren
trifft ihre Testdaten“), Streaming-Auswertung, Absatzgliederung (Text bleibt
2026-10-10 16:57:37 +02:00
unverändert, 3– 10 Sätze), Zwischenspeicher/Fortsetzen und die Kommandozeile.
2026-10-10 19:51:32 +02:00
`tests/test_extract_text.py` prüft den Gesamtablauf URL → Text, Sprachwahl
(Original-Audio, manuell vor automatisch) und Fehlerfälle.
2026-10-10 18:19:14 +02:00
`tests/test_yt_untertitel.py` prüft Spurauswahl, Aufruf von `yt-dlp` und
Fehlerfälle (ohne Netz, `yt-dlp` wird durch Fakes ersetzt).
2026-10-10 17:52:56 +02:00
`tests/test_vtt2txt.py` prüft die VTT-Umwandlung: jede `.vtt` in `testdaten/`
ergibt genau die zugehörige `.txt` , echte Wiederholungen bleiben erhalten,
2026-10-10 17:50:51 +02:00
dazu Muster, Ausgabeverzeichnis und Fehlerfälle.
2026-10-10 16:57:37 +02:00
2026-10-10 16:50:54 +02:00
## Zwischenstände
Jeder fertige Abschnitt und jede Absatzgliederung wird in `<Ausgabe>.parts/`
gespeichert. Ein erneuter Lauf überspringt alles, was schon berechnet ist.
Ändern sich Modell, Prompt, Glossar oder Text eines Abschnitts, wird genau dieser
Teil neu berechnet. Den Ordner kann man jederzeit löschen.
## Einstellungen
Oben in `rede_korrigieren.py` :
| Konstante | Standard | Bedeutung |
|---|---|---|
| `MODEL` | `qwen3:32b` | Ollama-Modell |
| `CHUNK_SIZE` | 1200 | Wörter pro Korrekturabschnitt |
| `MAX_WORD_DEVIATION` | 0.05 | Warnschwelle Wortzahl |
| `MAX_PARAGRAPH_SENTENCES` | 10 | längster erlaubter Absatz |
| `MIN_PARAGRAPH_SENTENCES` | 3 | kürzester gewünschter Absatz |
## Bekannte Grenzen
2026-10-10 19:23:28 +02:00
- Das Modell ändert gelegentlich Wörter eigenmächtig, auch sinnverändernd
(Magdeburg-Rede ohne Glossar: „Professor“ → „Professorin“, „gedeiliche“ →
„geregelte“ statt „gedeihliche“). Stichproben lohnen sich; gefundene Fälle
gehören ins Glossar.
2026-10-10 16:50:54 +02:00
- `qwen3:32b` ohne Denkmodus erkennt Hörfehler ohne Glossar nur teilweise und
setzt kaum `[prüfen: …]` -Marken. Bekannte Fehler gehören deshalb ins Glossar.
- Das Verbinden kurzer Absätze achtet nicht auf den Inhalt.
2026-10-10 19:23:28 +02:00
- `vtt2txt.py` erkennt Wiederholungen an der Überlappung aufeinanderfolgender
Untertitel-Blöcke. Bei Untertiteln ohne rollendes Fenster gehen deshalb zwei
direkt aufeinanderfolgende, identische Blöcke zu einem zusammen.
2026-10-10 16:50:54 +02:00
- Abkürzungen wie „z. B.“ oder „2. Weltkrieg“ können als Satzende gelten; das
beeinflusst nur mögliche Absatzgrenzen, nicht den Text.