Erzählung
npm run tts spricht jede Zeile von src/timeline.ts in public/audio/<lang>/<key>.wav,
mit Cartesias Wort-Zeitstempeln in <key>.words.json, und schreibt src/audio.generated.ts mit den
tatsächlichen Zeilenlängen neu. Zeilen werden nach Engine, Stimme, Modell, Geschwindigkeit und Text gecacht: Nur neue oder bearbeitete
Zeilen werden erneut gesprochen. npm run tts -- en oder -- es beschränkt es auf eine Sprache.
Cartesia Einrichtung
- Die Einstellungen befinden sich in
video.config.mjs(tts): Modellsonic-3.6-2026-08-27, Geschwindigkeit1. - EN-Stimme:
5568a7df-e5ab-4442-9fae-2e9ba1b15ad8(en-GB). CARTESIA_API_KEYwird in dieser Reihenfolge gesucht:- in der Umgebung;
- in
.envim Video-Ordner (gitignoriert;.env.examplekopieren); - in
~/Documents/repos/.env.
- Gib den Schlüssel niemals aus, gib ihn nicht per Echo aus und committe ihn nicht. Überprüfe, ob er existiert, ohne ihn anzuzeigen, zum
Beispiel
test -n "$CARTESIA_API_KEY" && echo set.
Engines und der Kokoro-Fallback
tts.engine in video.config.mjs:
auto(Standard): Cartesia, wenn ein Schlüssel gefunden wird und der Dienst antwortet; andernfalls wird die gesamte Sprache mit Kokoro (lokal, kostenlos) vertont und eine Warnung ausgegeben. Eine Sprache besteht niemals aus einer Mischung zweier Stimmen: Wenn Cartesia auf halbem Weg ausfällt, wird die gesamte Sprache mit Kokoro neu gemacht, und beim nächsten Durchlauf mit Cartesia wird sie erneut gemacht.cartesia: Fehlschlag statt Fallback.kokoro: Offline bleiben. Stimmen:af_bella(EN),ef_dora(ES). Kokoro gibt keine Wort- Zeitstempel, daher werden Untertitel proportional getimed.
Eine Warnung über Kokoro in der Ausgabe bedeutet, dass das Video nicht die Cartesia-Stimme hat: Sage dies, wenn du das Video übergibst.
Spanische Stimme
voices.es ist null, bis eine spanische Version erstellt wird. Wähle eine spanische Stimme aus der Cartesia-
Stimmbibliothek aus, höre eine Beispielzeile aus dem Skript an, notiere ihre ID in video.config.mjs
(es: { id: '<voice-id>', language: 'es' }) und füge 'es' zu SETTINGS.voices hinzu (und zu
SETTINGS.subtitles, falls spanische Untertitel gewünscht werden).
Aussprache
Das TTS spricht den Erzähltext; die Untertitel zeigen den geschriebenen Text. Wenn das TTS eine Zahl oder ein Symbol falsch ausspricht,
gib der Zeile eine gesprochene Form als viertes Argument von say und behalte die geschriebene Form des Artikels als Untertitel:
say(0.3, 'It solved 14/20 tasks.', 'Resolvió 14/20 tareas.', {
en: 'It solved fourteen out of twenty tasks.',
es: 'Resolvió catorce de veinte tareas.',
})
- Das TTS spricht die gesprochene Form (und der Cache spricht die Zeile erneut, wenn sie sich ändert); die Zeilenlänge stammt davon.
- Der Untertitel zeigt den geschriebenen Text, zeitlich proportional über die Zeile (Wort-Zeitstempel gehören zu den gesprochenen Wörtern, werden also für diese Zeile nicht verwendet).
- Schreibe die Zeile klar ("14/20", "83 %", "p = 0.0018") und füge eine gesprochene Form nur hinzu, wenn ein Anhören zeigt, dass das TTS sie falsch macht.
- Schrägstriche, Versionsstrings ("gpt-5.6"), Dateinamen und Akronyme sind die üblichen Problemstellen. Höre dir jede Zeile an, die eines davon enthält.
Audio-Qualitätssicherung
npm run audio-qa (schreibt out/audio-qa.md):
- normalisiert jede Zeile auf dieselbe Lautstärke (einmal pro Dateiversion);
- markiert eine Zeile als verzerrt (clipped), wenn ihr Spitzenpegel -0,1 dBFS erreicht;
- markiert eine Zeile als zu lang, wenn sie länger als 1,6x ihrer Schätzung aus der Textlänge dauert: ein Zeichen für verstümmelte oder wiederholte Sprache. Höre dir jede markierte Zeile an und sprich sie erneut ein (bearbeite den Text leicht oder lösche die wav), wenn sie falsch ist;
- nach
npm run rendermisst jeder Mix inout/gegen -16 LUFS integriert, ±1 LU (True Peak -1,5 dBTP) und beendet sich mit 1, wenn einer nicht dem Zielwert entspricht.
Führe nach dem Erzählen erneut npm run lint aus: Tatsächliche Längen ersetzen die Schätzungen und können das
Video über seine Ziellänge oder einen Untertitel über 17 Zeichen/s hinausbringen.
Musikbett
Ein sanftes Bett wird lokal erzeugt (npm run music, wird automatisch von npm run render erstellt, wenn es
fehlt; benötigt python3 mit numpy oder uv). Es wird auf 30 % seiner Lautstärke abgesenkt, während eine
Zeile läuft. Setze SETTINGS.music auf null für keine Musik.