Skip to main content
Einen einzelnen Aufruf an /audio/speech zu machen ist einfach. Einen echten Artikel zu vertonen ist der Punkt, an dem die interessanten Probleme auftauchen: Der Endpunkt akzeptiert höchstens 4096 Zeichen pro Anfrage, jede Stimme gehört zu einem bestimmten Modell, Audioformate unterscheiden sich von Modell zu Modell, und Text, der zum Lesen geschrieben wurde, sieht ganz anders aus als Text, der zum Hören geschrieben wurde. In diesem Tutorial arbeiten wir alle vier durch. Das Ergebnis ist ein Skript, das eine URL in eine einzige Audiodatei verwandelt:
Wir werden:
  1. Ein Modell und eine Stimme wählen, die zu langen Vertonungen passen
  2. Eine einzelne Speech-Anfrage stellen und das Audio speichern
  3. Einen langen Artikel in Chunks aufteilen, die in das Zeichenlimit passen
  4. Die synthetisierten Chunks zu einer Datei ohne hörbare Nähte zusammenfügen
  5. Den Artikel in etwas umschreiben, das sich anzuhören lohnt
  6. Die Teile kombinieren und uns dann Streaming für den interaktiven Einsatz ansehen

Einrichtung

Du brauchst Python 3.9 oder neuer, das Paket requests und einen Venice-API-Schlüssel.

1. Ein Modell und eine Stimme wählen

Stimmen gehören zu Modellen. Eine Stimme aus einer Familie an ein Modell einer anderen zu senden ist der häufigste Anfängerfehler, beginne also damit aufzulisten, was jedes Modell tatsächlich akzeptiert:
model_spec.voices ist die maßgebliche Stimmenliste für ein Modell, und supported_formats sagt dir, welche response_format-Werte es akzeptiert. Lasse das | length aus der Abfrage weg, um die Stimmennamen selbst auszugeben. Wir verwenden tts-xai-v1 mit der Stimme eve. Es unterstützt pcm, was das Zusammenfügen von Chunks in Abschnitt 4 einfach macht.
Die Synthesegeschwindigkeit variiert zwischen TTS-Modellen weit stärker als die Ausgabequalität, und der Unterschied ist groß genug, um deine Architektur zu ändern. Miss eine realistische Anfrage gegen zwei oder drei Kandidaten, bevor du dich festlegst. Ein Chunk, den ein Modell in wenigen Sekunden zurückgibt, kann bei einem anderen mehrere Minuten dauern.

2. Eine einzelne Anfrage stellen

Der Response-Body ist rohes Audio und kein JSON, also schreibe die Bytes direkt in eine Datei.
Nicht passende Kombinationen werden abgelehnt, bevor irgendein Audio erzeugt wird, und der Fehler sagt dir, was stattdessen funktioniert hätte:

3. Text am 4096-Zeichen-Limit aufteilen

Das Feld input akzeptiert höchstens 4096 Zeichen. Längerer Text wird direkt abgelehnt statt stillschweigend abgeschnitten:
Also teilen wir den Artikel zuerst auf. Das Aufteilen an Satzgrenzen ist wichtig, denn ein Chunk, der mitten im Satz endet, erzeugt an der Verbindungsstelle ein hörbares Stolpern. Erstelle narrate.py:
Bei einem 5362 Zeichen langen Skript ergibt das vier Chunks, die jeweils an einem Satzende schließen:
Der Standardwert für max_chars ist 1500 statt eines Werts nahe der 4096er-Obergrenze, und das ist Absicht. Die Synthesezeit wächst mit der Eingabelänge, kleinere Chunks kommen also schneller zurück und beenden – weil sie parallel laufen – die gesamte Aufgabe insgesamt schneller. Sie machen außerdem Wiederholungsversuche günstig, wenn eine Anfrage fehlschlägt.

4. Die Chunks zu einer Datei zusammenfügen

Kodierte Audioformate wie MP3 zu verketten ist unzuverlässig, weil jeder Chunk seine eigenen Frame-Header trägt. pcm anzufordern vermeidet das Problem vollständig. PCM sind rohe Samples ohne Container, das Zusammenfügen ist also nur ein Anhängen von Bytes, und das wave-Modul aus Pythons Standardbibliothek schreibt den Header für uns.
Ein einzelner Chunk kommt schnell zurück, gemessen daran, wie viel Audio er enthält:
Diese Anfrage brauchte etwa 13 Sekunden, um 89 Sekunden Sprache zu erzeugen. Die vier Chunks nebenläufig auszuführen, hält die Gesamtdauer im Rahmen: Die vollständige Vertonung unten brauchte 15 Sekunden Wanduhrzeit. ThreadPoolExecutor.map gibt Ergebnisse in der Reihenfolge zurück, in der die Eingaben übergeben wurden, sodass die Chunks in Leserichtung landen, obwohl sie gleichzeitig synthetisiert wurden.
Rohes PCM trägt keine Sample-Rate, du musst also beim Schreiben des WAV-Headers die richtige selbst angeben, und sie ist modellspezifisch. tts-xai-v1 liefert 24 kHz, während tts-gradium-v1 48 kHz liefert. Rate falsch, und die Vertonung spielt mit falscher Geschwindigkeit und Tonhöhe.
Um die Rate für ein beliebiges Modell zu finden, fordere einen kurzen Clip als wav an und lies den Header, den es zurückliefert:

5. Text so aufbereiten, dass er sich richtig anhört

Gescrapte Markdown-Inhalte wörtlich vorzulesen ist nahezu unerträglich anzuhören. URLs sind das deutlichste Beispiel. Ein Sprachmodell buchstabiert sie Zeichen für Zeichen aus, sodass https://docs.venice.ai/llms.txt so klingt:
h t t p s Doppelpunkt Schrägstrich Schrägstrich docs Punkt venice Punkt a i l l m s Punkt t x t
Überschriften, Aufzählungszeichen, Tabellen und Codeblöcke verursachen kleinere Versionen desselben Problems. Statt Markdown mit regulären Ausdrücken zu bekämpfen, können wir ein Chat-Modell bitten, den Artikel als etwas umzuschreiben, das zum Sprechen gedacht ist. Erstelle article_to_audio.py:
Die URL_PATTERN-Ersetzung bleibt als Sicherheitsnetz für den gelegentlichen Link erhalten, den das Modell übrig lässt.

6. Alles zusammenfügen

Der Einstiegspunkt scrapt, schreibt das Skript, speichert es und vertont:
script.txt neben dem Audio abzuspeichern ist die zwei Zeilen wert. Wenn eine Vertonung falsch klingt, zeigt das Skript fast immer, warum, und du kannst es beheben, ohne für eine erneute Synthese zu zahlen.
Knapp unter sechs Minuten Vertonung, erzeugt in etwa fünfzehn Sekunden. Das Skript beginnt jetzt mit Prosa statt mit Navigationsbeiwerk:
Venice is built on a simple but powerful principle. User privacy comes first. The platform’s entire architecture flows from this philosophical commitment.
Um eine Vertonung zu prüfen, ohne sie ganz anhören zu müssen, schicke das Audio zurück durch /audio/transcriptions und vergleiche das Transkript mit script.txt. Die letzten zwanzig Sekunden zu transkribieren ist eine schnelle Möglichkeit, um zu bestätigen, dass die Chunks in der richtigen Reihenfolge zusammengefügt wurden, und findet in Sekunden fehlende Chunks und ausbuchstabierte URLs.

Streaming für den interaktiven Einsatz

Batch-Vertonung optimiert die Gesamtzeit. Eine Sprachschnittstelle hat die gegenteilige Priorität, nämlich das erste Audio so schnell wie möglich auszugeben. Wenn du streaming: true setzt, wird der Body Satz für Satz zurückgegeben, während er erzeugt wird, sodass die Wiedergabe nach etwa einer Sekunde starten kann, statt auf den kompletten Clip zu warten.
Bevorzuge pcm gegenüber mp3, wenn du die Web Audio API eines Browsers oder direkt ein Audiogerät fütterst, da hier kein Dekodierschritt nötig ist.

Nützliche Anfrageoptionen

Fehler

Weil die Chunks voneinander unabhängig sind, kostet ein Fehlschlag immer nur einen von ihnen, und synthesize für diesen Chunk erneut auszuführen ist stets sicher.

Nächste Schritte

Ein paar natürliche Erweiterungen von hier aus:
  • Audio nach einem Hash von Text, Stimme und Modell cachen, damit unveränderte Absätze nie erneut synthetisiert werden.
  • Eine geklonte Stimme über Voice Cloning einsetzen, damit die Vertonung deine eigene verwendet.
  • Den Quelltext erzeugen, statt ihn zu scrapen, mit Zitierte Antworten mit Websuche.
  • Intro- oder Hintergrund-Audio mit Musik und Soundeffekte hinzufügen.

Text-to-Speech

Referenz für den Speech-Endpunkt und seine Parameter.

Voice Cloning

Mit einer eigenen Stimme statt eines Presets vertonen.

Zitierte Antworten mit Websuche

Den Text erzeugen, den dieses Tool vertont.

Speech-to-Text

Audio transkribieren, um eine Vertonung durchgehend zu verifizieren.