Python TTS pipeline with remote processing support at vast.ai
Find a file
2026-04-26 21:45:18 +02:00
.github quality test 2026-04-26 18:48:36 +02:00
.vscode technik der IP netze 2026-04-21 06:17:19 +02:00
books@ca23747023 quality test 2026-04-26 18:48:36 +02:00
docs increase disc size 2026-04-26 21:45:18 +02:00
models/piper guide to BA, start rework 2026-04-21 09:42:25 +02:00
src increase disc size 2026-04-26 21:45:18 +02:00
tests quality test 2026-04-26 18:48:36 +02:00
.gitignore guide to BA, start rework 2026-04-21 09:42:25 +02:00
.gitmodules improve audio qualtiy 2026-04-26 17:09:45 +02:00
extract_text.py improve SW arch 2026-04-21 15:22:47 +02:00
generate_podcast.py quality test 2026-04-26 18:48:36 +02:00
LICENSE Initial commit 2026-04-19 12:45:49 +02:00
optimize_text.py improve audio qualtiy 2026-04-26 17:09:45 +02:00
README.md quality test 2026-04-26 18:48:36 +02:00
regenerate_feeds.py improve SW arch 2026-04-21 15:22:47 +02:00
requirements improve audio qualtiy 2026-04-26 17:09:45 +02:00
test_quality.py quality test 2026-04-26 18:48:36 +02:00
TODO.txt quality test 2026-04-26 18:48:36 +02:00
translate.py improve SW arch 2026-04-21 15:22:47 +02:00

PDF-to-Audiobook Pipeline

Python-Pipeline, die PDFs in Hörbücher (MP3) umwandelt mit optionaler Übersetzung und Podcast-Feed-Generierung.

Pipeline-Übersicht

PDF ──► extract_text.py ──► books/<name>/text.txt
                            books/<name>/chapters/*.txt

     ──► translate.py   ──► books/<name>/chapters/de/*.txt

     ──► optimize_text.py ► books/<name>/chapters/*.txt (in-place)
                            books/<name>/chapters/de/*.txt (in-place)

     ──► generate_podcast.py ──► books/<name>/out/*.mp3
                                 books/<name>/out/feed.xml                                 books/out/<name>_<lang>.mp3 (Overall)
                                 books/out/feed.xml (Overall-Feed)```

Vier High-Level-Skripte steuern die Pipeline:

| Schritt              | Skript                | Beschreibung                                                |
| -------------------- | --------------------- | ----------------------------------------------------------- |
| 1. Extraktion        | `extract_text.py`     | PDF → Text → Kapitel (automatisch via Lesezeichen oder LLM) |
| 2. Übersetzung       | `translate.py`        | Kapitel EN↔DE übersetzen (Google oder OpenRouter)           |
| 2b. TTS-Optimierung  | `optimize_text.py`    | Kapitel-Texte mittels LLM für TTS aufbereiten (optional)    |
| 3. Audio             | `generate_podcast.py` | Kapitel → MP3 + optionaler Podcast-RSS-Feed + Overall-Feed |
| 4. Feed-Regeneration | `regenerate_feeds.py` | Podcast-Feeds und Cover neu generieren                      |

## Voraussetzungen

- Python 3.11+
- ffmpeg (`apt install ffmpeg` / `brew install ffmpeg`)
- Für GPU-Provider: SSH-Key im jeweiligen Dashboard hinterlegt
- API-Keys je nach Provider:
  - `OPENROUTER_API_KEY`  für OpenRouter TTS und LLM-Übersetzung
  - `RUNPOD_API_KEY`  für RunPod GPU-Instanzen
  - Google Cloud: `gcloud auth application-default login` (Application Default Credentials)
  - vast.ai CLI (`vastai`)  für vast.ai GPU-Instanzen

## Installation

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements

Verwendung

1. Text aus PDF extrahieren

# Kapitel-Erkennung über PDF-Lesezeichen (Standard)
python3 extract_text.py buch.pdf --name meinbuch

# Kapitel-Erkennung über LLM (OpenRouter)
python3 extract_text.py buch.pdf --name meinbuch --provider openrouter

# Mit JSON-Konfiguration für manuelle Kapitel-Grenzen
python3 extract_text.py buch.pdf --name meinbuch --config chapters.json

Ergebnis: books/meinbuch/text.txt und books/meinbuch/chapters/*.txt

2. Kapitel übersetzen (optional)

# Englisch → Deutsch mit Google Translate (kostenlos)
python3 translate.py meinbuch

# Englisch → Deutsch mit OpenRouter (LLM, höhere Qualität)
python3 translate.py meinbuch --provider openrouter

# Deutsch → Englisch
python3 translate.py meinbuch --direction de-en

Bei OpenRouter wird vor der Übersetzung eine Kostenprognose angezeigt und nach Abschluss mit den tatsächlichen Kosten verglichen.

2b. Text für TTS optimieren (optional)

Optimiert Kapitel-Texte mittels LLM für die TTS-Synthese: entfernt Klammern, Referenzen, Fußzeilen-Fragmente, schreibt Abschnittsnummern wie "1.3.1" und Abkürzungen lesbar aus, und wandelt Tabellen/Figur-Verweise in fließenden Text um. Zeigt vor dem Start eine Kostenprognose und vergleicht nach Abschluss die tatsächlichen Kosten.

# Alle Kapitel optimieren (EN + DE)
python3 optimize_text.py meinbuch

# Nur Deutsch
python3 optimize_text.py meinbuch -l de

# Mit anderem Modell
python3 optimize_text.py meinbuch -m google/gemini-2.5-flash

Ergebnis: Die Kapitel-Dateien werden direkt überschrieben (in-place). Eine Tracking-Datei .tts_optimized merkt sich, welche Dateien bereits optimiert wurden.

3. Audio generieren

# Cloud-TTS über OpenRouter API (kein GPU nötig)
python3 generate_podcast.py meinbuch --provider openrouter

# Nach optimize_text.py werden die optimierten Texte automatisch verwendet
python3 generate_podcast.py meinbuch --provider google

# Google TTS mit bestimmter Stimme
python3 generate_podcast.py meinbuch --provider google --voice Kore

# GPU-Instanz auf vast.ai (Coqui XTTS v2)
python3 generate_podcast.py meinbuch --provider vast

# GPU-Instanz auf RunPod
python3 generate_podcast.py meinbuch --provider runpod

# Mit Podcast-Feed (Nextcloud-Freigabelink)
python3 generate_podcast.py meinbuch --provider openrouter \
  --share-url https://cloud.example.com/s/TOKEN

# Nur eine Sprache verarbeiten
python3 generate_podcast.py meinbuch --provider openrouter --lang de

# Overall-Feed nicht aktualisieren
python3 generate_podcast.py meinbuch --provider openrouter --no-overall-feed

# Cloud-TTS über Google Cloud Chirp 3: HD (kein GPU nötig, hohe Qualität)

Ergebnis: `books/meinbuch/out/*.mp3` (und ggf. `feed.xml`)

## TTS-Provider

| Provider     | Modell                            | GPU nötig              | Kosten                                |
| ------------ | --------------------------------- | ---------------------- | ------------------------------------- |
| `openrouter` | OpenAI gpt-4o-mini-tts            | Nein                   | ~$0.60 / 1M Zeichen                   |
| `google`     | Google Chirp 3: HD                | Nein                   | $30 / 1M Zeichen (1M/Monat kostenlos) |
| `mistral`    | Voxtral Mini TTS                  | Nein                   | $16 / 1M Zeichen                      |
| `voxtral`    | Voxtral 4B TTS                    | Ja (lokal, 16 GB VRAM) | Kostenlos (lokaler vLLM-Server)       |
| `local`      | XTTS v2 / F5-TTS / Kokoro / Piper | Ja (lokal)             | Kostenlos                             |
| `vast`       | Coqui XTTS v2                     | Ja (gemietet)          | Variabel (Stundenpreis)               |
| `runpod`     | Coqui XTTS v2                     | Ja (gemietet)          | Variabel (Stundenpreis)               |

Bei GPU-Providern werden automatisch Angebote gesucht und eine Auswahl mit Kostenprognose angezeigt (günstigste Gesamtkosten, günstigste Stundenrate, beste Preis-Leistung, schnellste). Nach Abschluss wird ein Vergleich zwischen prognostizierten und tatsächlichen Kosten ausgegeben.

### Lokale TTS-Engines

Die Skripte `text_to_audio.py`, `batch_to_audio.py` und `pdf_to_audio.py` unterstützen zwei lokale TTS-Engines:

| Engine        | Flag                 | Modell                                          | Besonderheiten                           |
| ------------- | -------------------- | ----------------------------------------------- | ---------------------------------------- |
| Coqui XTTS v2 | `-e xtts` (Standard) | `tts_models/multilingual/multi-dataset/xtts_v2` | Eingebaute Stimme oder Voice-Cloning     |
| F5-TTS        | `-e f5tts`           | F5TTS_v1_Base (DE: hvoss-techfak/F5-TTS-German) | Voice-Cloning, Referenz-WAV erforderlich |

**F5-TTS Installation:** `pip install f5-tts`

**Beispiele:**

```bash
# Lokale TTS mit Coqui XTTS v2 (Standard)
python3 src/text_to_audio.py kapitel.txt -o out.mp3

# Lokale TTS mit F5-TTS (Referenz-WAV erforderlich)
python3 src/text_to_audio.py kapitel.txt -o out.mp3 -e f5tts -s stimme.wav

# F5-TTS mit expliziter Transkription der Referenz-WAV
python3 src/text_to_audio.py kapitel.txt -o out.mp3 -e f5tts -s stimme.wav \
  --ref-text "Text der Referenzaufnahme"

# Batch mit F5-TTS
python3 src/batch_to_audio.py -e f5tts -s stimme.wav --chapters-dir books/meinbuch/chapters

# PDF direkt mit F5-TTS
python3 src/pdf_to_audio.py buch.pdf -o out.mp3 -e f5tts -s stimme.wav

Für Deutsch wird automatisch das Community-Modell hvoss-techfak/F5-TTS-German geladen. Für andere Sprachen wird das Standard-Multilingual-Modell (zh & en) verwendet.

Projektstruktur

├── extract_text.py            # Schritt 1: PDF → Kapitel (CLI)
├── translate.py               # Schritt 2: Kapitel übersetzen (CLI)
├── optimize_text.py           # Schritt 2b: Texte für TTS optimieren (CLI)
├── generate_podcast.py        # Schritt 3: Kapitel → MP3 + Feed (CLI)
├── regenerate_feeds.py        # Feed-Regenerierung (CLI)
├── requirements               # pip-Abhängigkeiten
├── src/
│   ├── models.py              # Datenmodelle (Cost, ChapterBoundary, Book)
│   ├── metadata.py            # Metadaten-Verwaltung (Metadata-Klasse + Funktionen)
│   ├── orchestrate_extraction.py   # Extraktions-Orchestrator
│   ├── orchestrate_translation.py  # Übersetzungs-Orchestrator
│   ├── orchestrate_optimization.py # Optimierungs-Orchestrator
│   ├── orchestrate_audio.py        # Audio-Orchestrator
│   ├── orchestrate_feed.py         # Feed-Orchestrator
│   ├── providers/             # Provider-Interfaces (Protocol) und Implementierungen
│   │   ├── tts.py             # TTSProvider-Protocol + Registry (8 Provider)
│   │   ├── translate.py       # TranslateProvider-Protocol + Registry
│   │   ├── splitter.py        # ChapterSplitter-Protocol + Registry
│   │   └── remote.py          # RemoteExecutor-Protocol + Registry
│   ├── pdf_to_text.py         # PDF-Textextraktion (pypdf)
│   ├── split_chapters.py      # Kapitel-Erkennung (Lesezeichen/LLM/JSON)
│   ├── clean_chapters.py      # Textbereinigung für TTS
│   ├── optimize_for_tts.py    # LLM-gestützte TTS-Textoptimierung
│   ├── translate_chapters.py  # Übersetzungs-Engine (Google/OpenRouter)
│   ├── text_to_audio.py       # Lokale TTS (XTTS v2 / F5-TTS / Kokoro / Piper)
│   ├── openrouter_run.py      # OpenRouter TTS-API Batch
│   ├── google_run.py          # Google Cloud TTS (Chirp 3: HD) Batch
│   ├── mistral_run.py         # Mistral Voxtral Mini TTS Batch
│   ├── voxtral_run.py         # Voxtral 4B TTS (lokaler vLLM-Server) Batch
│   ├── vast_run.py            # vast.ai GPU-Automatisierung
│   ├── runpod_run.py          # RunPod GPU-Automatisierung
│   ├── generate_feed.py       # Podcast-RSS-Feed-Generator
│   ├── overall_feed.py        # Overall-Feed für alle Bücher (books/out/)
│   ├── audio.py               # AudioAssembler (MP3/WAV-Zusammenfügung)
│   ├── cover.py               # CoverProcessor (Podcast-Cover)
│   ├── cost.py                # CostEstimator (Kostenprognose/-vergleich)
│   ├── retry.py               # Zentrale Retry-Logik
│   ├── chunk_splitter.py      # Zentraler Chunk-Splitter
│   ├── file_utils.py          # Datei-Hilfsfunktionen
│   ├── http_client.py         # HTTP-Client mit Retry
│   ├── gpu.py                 # GPU-Erkennung
│   ├── ssh_utils.py           # SSH/rsync-Hilfsfunktionen
│   ├── batch_to_audio.py      # Standalone-Batch-TTS
│   └── pdf_to_audio.py        # All-in-One PDF → MP3
├── books/
│   └── <name>/
│       ├── text.txt           # Extrahierter Volltext
│       ├── metadata.txt       # Key-Value-Metadaten
│       ├── chapters.txt       # Kapitel-Titel-Zuordnung
│       ├── chapters/*.txt     # Kapitel (EN, ggf. TTS-optimiert)
│       ├── chapters/de/*.txt  # Kapitel (DE, ggf. TTS-optimiert)
│       └── out/{model}/{lang}/*.mp3  # Generierte Audiodateien
├── books/
│   └── out/                       # Overall-Feed: zusammengefügte MP3s + feed.xml
├── tests/                     # pytest-Testsuite
└── docs/                      # Architektur, SWDD, Provider-Dokumentation

Umgebungsvariablen

Variable Verwendung
OPENROUTER_API_KEY OpenRouter API (TTS + Übersetzung + LLM-Kapitel-Erkennung)
RUNPOD_API_KEY RunPod GPU-Pods
GOOGLE_APPLICATION_CREDENTIALS Google Cloud TTS (optional, alternativ gcloud auth application-default login)
Für vast.ai wird die vastai CLI verwendet (Authentifizierung über vastai set api-key).

Lizenz

Apache License 2.0 siehe LICENSE.