TTS-Pipeline
Das CMS erzeugt Vorlese-Audios für Kategoriebezeichnungen, Storytitel sowie Text- und Linkinhalte von Stories. Audio und Wort-Zeitmarken sind Bestandteil des veröffentlichten Inhalts; die Joblogik bleibt unabhängig vom gewählten Audioanbieter.
Inhalt speichern
│
▼
vertontes Feld + Text-Hash
│
▼
TTS-Job: pending → running → done / failed
│
├── Qwen3-TTS (lokales Python-Skript)
├── KugelAudio
└── ElevenLabs
│
▼
Audio + Wort-Zeitmarken → Media Library → ttsJobs am InhaltJobmodell
Ein Job enthält unter anderem Feldpfad, Locale, Text-Hash, Status, Anzahl der Versuche, Fehler, Audio und Zeitmarken. Der Text-Hash erkennt, ob ein gespeichertes Audio noch zum aktuellen Text passt.
Automatische Auslöser
- Beim Anlegen einer Kategorie oder Story werden alle benötigten Jobs eingereiht.
- Beim Ändern einer Kategoriebezeichnung werden deren Jobs synchronisiert.
- Beim Ändern von Storytitel oder Slides werden die Storyjobs synchronisiert.
- Unveränderte Text-Hashes behalten ihr fertiges Audio; veränderte Felder
werden wieder auf
pendinggesetzt. - Veröffentlichen und Zurückziehen lösen keine neue Generierung aus.
- Eine Veröffentlichung wird abgewiesen, solange für die Locale Jobs den
Status
pendingoderrunninghaben.
Das CMS entfernt nicht mehr referenzierte, von der Pipeline erzeugte Audiodateien kontrolliert. Die TTS-Metadaten werden vom System verwaltet und sind nicht als redaktionelle Freitextfelder gedacht.
Worker
Der Worker läuft im Strapi-Prozess, beansprucht offene Aufträge und ruft den konfigurierten Adapter auf. Abgebrochene, fehlgeschlagene und nach Neustarts liegengebliebene Aufträge können kontrolliert erneut verarbeitet werden.
Zugriffsschutz
Status, Enqueue, Cancel, Recover und das zentrale Audio-Dashboard verwenden dieselbe aktive Admin-Session wie die Strapi-Oberfläche. Der Admin-Fetch-Client sendet das kurzlebige Zugriffstoken automatisch; ein eigenes TTS-Secret wird weder benötigt noch in das Browser-Bundle eingebettet. Öffentliche Requests, abgelaufene Sessions und Content-API-Tokens erhalten keinen Zugriff.
Nach der Authentifizierung greift Strapis Content-Manager-RBAC. Lesen von
Statusdaten erfordert read, Änderungen erfordern update für den jeweiligen
Content-Type. Das Dashboard setzt die Rechte für Stories und Kategorien
voraus. Verändernde Routen sind zusätzlich auf zehn Requests je Route und IP
innerhalb von 60 Sekunden begrenzt. Ein vorgeschalteter Reverse Proxy kann für
mehrere CMS-Instanzen ergänzend ein verteiltes Limit durchsetzen.
Locale-Konfiguration
Provideroptionen können pro vollständiger Locale, Sprache oder global gesetzt
werden. Für en-US gilt beispielsweise:
..._EN_US → ..._EN → globaler WertQwen3-TTS
Qwen wird über ein separates Python-Skript aufgerufen. Modellgewichte,
Python-Umgebung, Referenzaufnahmen und optionaler Forced Aligner werden nicht
mit npm install installiert. Für Voice Cloning muss das Transkript exakt zur
Referenzaufnahme passen. Der Forced Aligner liefert Wort-Zeitmarken; ohne
lokale GPU ist die Generierung je nach Modell deutlich langsamer.
KugelAudio
KugelAudio wird als Cloud-Dienst über API-Key, Modell und Voice-ID angebunden.
Die WebSocket-Übertragung ist der Standard, weil die Wort-Zeitmarken darüber
mitgeliefert werden. Mit KUGELAUDIO_REQUIRE_TIMESTAMPS=true gilt ein Audio
ohne Zeitmarken als fehlgeschlagen. Sample-Rate, Normalisierung, Sprache und
Stimme können global oder je Locale konfiguriert werden.
ElevenLabs
ElevenLabs erzeugt über die API PCM-Audio, das der Adapter als WAV speichert.
Für die in der App verwendete wortweise Hervorhebung ruft der Adapter bei
ELEVENLABS_FORCE_ALIGNMENT=true zusätzlich Forced Alignment auf. API-Key,
Voice-ID, Modell, Ausgabeformat und Sprachcode können global oder je Locale
gesetzt werden.
Änderungen an Worker, Lifecycle-Hooks, Wiederherstellung oder automatischem Löschen von Medien sind datenrelevant und benötigen gezielte Tests.