Demo API TTS: Przykłady żądań i odpowiedzi w czasie rzeczywistym
To demo pokazuje rzeczywiste żądania, które możesz uruchomić szybko, oraz format odpowiedzi, który jest zwracany. API jest modelem tekstowym, więc wyjściem jest tekst do odczytu, JSON i wywoływanie funkcji, które oddzielny silnik syntez mowy może następnie przeczytać na głos.
Zaktualizowano

Zanim uruchomisz cokolwiek
Uczciwe ostrzeżenie dla każdego, kto oczekuje wciśnięcia play i usłyszenia głosu: to demo tts api nie produkuje dźwięku. Usługa zwraca tekst z jednego modelu, uncensored, przez POST /v1/chat/completions. Istnieje drugi endpoint, GET /v1/models, do listowania tego, co jest dostępne. Nic nie zwraca audio, obrazów ani embeddingów.
Dlaczego demo? Ponieważ wiele projektów syntezy mowy potrzebuje dokładnie tego elementu: pisarza scenariusza, czyszczenia tekstu, podziału decydującego, kto co mówi. Poniższe przykłady pokazują te zadania, a format wyjściowy to to, co Twój kod syntezy mowy będzie parsować.
Potrzebujesz klucza. Zarejestruj się na stronie klucza API z Google lub z e-mailem i hasłem, a następnie aktywuj kredyt $0.50 jednym kliknięciem. Jest ważny przez 7 dni i nie wymaga karty. Wyeksportuj klucz, aby poniższe polecenia mogły go odczytać:
export XTTS_API_KEY="paste-your-key-here"
curl -s https://api.xtts.cc/v1/models -H "Authorization: Bearer $XTTS_API_KEY" | grep uncensored
Jeśli to wywołanie zwróci listę JSON, która zawiera uncensored, klucz działa i możesz kontynuować.
Demo 1: zwykłe żądanie
Najmniejsze użyteczne wywołanie prosi o krótki akapit w stylu mówionym:
curl -s https://api.xtts.cc/v1/chat/completions \
-H "Authorization: Bearer $XTTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [
{"role": "system", "content": "You write short lines for a voice actor. No stage directions."},
{"role": "user", "content": "Welcome listeners to a show about lighthouses. Two sentences."}
],
"temperature": 0.7,
"max_tokens": 120
}'
Odpowiedź wygląda jak poniższy przykład. Tekst wewnątrz content będzie się różnić przy każdym uruchomieniu, więc traktuj go jako ilustrację struktury, a nie jako nagrane wyjście.
{
"id": "chatcmpl-example",
"object": "chat.completion",
"model": "uncensored",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Welcome to the show. Tonight we climb the stairs of the world's loneliest lighthouses."
},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 38, "completion_tokens": 21, "total_tokens": 59}
}
Twój kod syntezy mowy odczytuje choices[0].message.content. finish_reason mówi Ci, dlaczego generowanie się zakończyło: stop dla naturalnego końca, length jeśli max_tokens skrócił go. Jeśli pominiesz max_tokens, wynik może użyć tego, co pozostanie z okna kontekstu 100 000 tokenów, które obejmuje prompt i wynik razem.
Co mówią nagłówki
Dodaj -i do polecenia curl i zobaczysz X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests i X-RateLimit-Limit-Concurrency. Nagłówek salda jest przydatny w demo, ponieważ możesz obserwować, jak spada o niewielką kwotę po każdym wywołaniu. Dla tego żądania użycie powyżej wynosi 38 x $0.15 / 1 000 000 plus 21 x $0.50 / 1 000 000, co daje $0.0000057 plus $0.0000105, około $0.0000162.
Demo 2: strumieniowanie scenariusza
Dla audio rzadko chcesz czekać na pełny tekst. Dodaj "stream": true, a API wysyła zdarzenia wysyłane przez serwer, po małym kawałku tekstu na raz. Poniższy przykład w Node.js drukuje tekst w miarę jego przybywania, co jest momentem, w którym mógłbyś podać kolejkę zdań.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.xtts.cc/v1",
apiKey: process.env.XTTS_API_KEY,
});
const stream = await client.chat.completions.create({
model: "uncensored",
stream: true,
messages: [
{ role: "user", content: "Read a four-line weather report for a coastal town." },
],
});
for await (const chunk of stream) {
const piece = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(piece);
}
process.stdout.write("\n");
Uruchom go jako moduł ES (zapisz jako demo.mjs i uruchom node demo.mjs po npm install openai). Przez sieć każde zdarzenie to linia zaczynająca się od data:, po której następuje JSON, a strumień zamyka się końcowym znacznikiem. Zużycie tokenów jest raportowane na końcu strumienia. Jedna kwestia ma znaczenie dla planowania: zapytanie strumieniowe utrzymuje swój slot współbieżności do końca strumienia, więc wolny konsument może zablokować Twoje kolejne zapytanie.
Demo 3: wywoływanie funkcji jako router mowy
Wywoływanie funkcji pozwala modelowi zwrócić uporządkowaną instrukcję zamiast prozy. W projekcie głosowym jest to czysty sposób na wybór stylu dostawy dla każdej linii. Definiujesz funkcję o nazwie say, a model wypełnia jej argumenty. Twój kod decyduje następnie, co z nimi zrobić. Model nie wykonuje niczego sam.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.xtts.cc/v1", api_key=os.environ["XTTS_API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "say",
"description": "Queue one line for the voice engine.",
"parameters": {
"type": "object",
"properties": {
"text": {"type": "string"},
"style": {"type": "string", "enum": ["calm", "urgent", "whisper"]},
},
"required": ["text", "style"],
},
},
}]
messages = [
{"role": "system", "content": "Always answer by calling say, once per line."},
{"role": "user", "content": "The alarm sounds. The guard tells everyone to leave."},
]
r = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = r.choices[0].message
for call in msg.tool_calls or []:
args = json.loads(call.function.arguments)
print(args["style"], "->", args["text"])
Argumenty przybywają jako ciąg JSON, więc sparsuj je i zwaliduj przed użyciem. Modele mogą wyprodukować styl spoza Twojego enum lub pominąć pole, a niezweryfikowana wartość nigdy nie powinna trafić do Twojego silnika. Jeśli chcesz, aby rozmowa kontynuowała się, dołącz wiadomość asystenta i odpowiedź z role: "tool" i pasującym tool_call_id, a następnie wywołaj API ponownie.
Podczas strumieniowania wywołania narzędzi przychodzą w kawałkach. Nazwa funkcji przychodzi pierwsza, a ciąg argumentów buduje się przez fragmenty, więc zbieraj fragmenty według indeksu i sparsuj raz, gdy strumień się zakończy.
Demo 4: tryb JSON dla listy obsady
Jeśli wolisz pominąć definicje funkcji, tryb JSON daje poprawny JSON w treści wiadomości. Jest to dobre dopasowanie do zamiany surowej sceny na linie dla każdego mówcy.
curl -s https://api.xtts.cc/v1/chat/completions \
-H "Authorization: Bearer $XTTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"response_format": {"type": "json_object"},
"temperature": 0.2,
"messages": [
{"role": "system", "content": "Return JSON: {\"lines\": [{\"speaker\": string, \"text\": string}]}"},
{"role": "user", "content": "Ana asks Ben to hold the ladder. Ben agrees reluctantly."}
]
}'
Tryb JSON gwarantuje, że wyjście zostanie sparsowane, a nie że pasuje do Twojego kształtu. Opisz kształt w prompcie, jak wyżej, i sprawdź klucze w kodzie. Niska temperatura utrzymuje strukturę stabilną.
Demo 5: długi dokument w jednym żądaniu
Okno kontekstu wynosi 100 000 tokenów, dzielone przez prompt i uzupełnienie. To wystarczy, aby wysłać długą transkrypcję lub całą krótką opowieść i poprosić o wersję napisaną na uszy. Treść żądania może mieć do 8 MB, więc rozmiar rzadko jest limitem; limitem jest liczba tokenów.
Oto koszt ciężkiego wywołania. Wyślij 80 000 tokenów i otrzymaj 2 000. Dane wejściowe: 80 000 x $0,15 / 1 000 000 = $0,012. Dane wyjściowe: 2 000 x $0,50 / 1 000 000 = $0,001. Łącznie $0,013, więc kredyt próbny $0,50 pokryłby około 38 takich wywołań. Długie dane wejściowe są tanie w porównaniu z długimi danymi wyjściowymi, dlatego podsumowania i przeróbki dużych tekstów są przystępne, podczas gdy wygenerowanie całej powieści na raz nie jest.
Praktyczna wskazówka dla długich inputów: umieść instrukcje na początku i powtórz kluczową zasadę na końcu. Modele najlepiej podążają za najnowszą instrukcją, a jednowierszowe przypomnienie po 80 000 tokenach tekstu źródłowego kosztuje prawie nic.
Odczytywanie błędów w demo
Zepsuj coś celowo raz, aby później to rozpoznać. Wyślij żądanie z błędnym kluczem i otrzymasz błąd uwierzytelniania zamiast odpowiedzi. Wyślij dziesięć żądań w tym samym momencie z kluczem próbnym i niektóre zwrócą się jako HTTP 429.
429 ma trzy przyczyny, a kod błędu je rozróżnia:
rate_limitedoznacza zbyt wiele żądań w ciągu jednej minuty: 60 na kluczu próbnym, 300 na pełnym kluczu.concurrencyoznacza zbyt wiele żądań w locie naraz: 2 na kluczu próbnym, 8 na pełnym kluczu.- 429 z nagłówkiem
Retry-After: 5oznacza, że usługa była chwilowo przeciążona. Poczekaj pięć sekund i wyślij ponownie.
Nieudane lub odrzucone żądania nie są rozliczane, więc błędy nic nie kosztują. Aby zobaczyć limity, które ma Twój klucz, przeczytaj X-RateLimit-Limit-Requests i X-RateLimit-Limit-Concurrency w dowolnej normalnej odpowiedzi. Mała pętla ponawiania, która śpi przez wartość Retry-After, lub pięć sekund, gdy brakuje, to wszystko, czego potrzebuje skrypt demo.
Co spróbować dalej
Gdy te cztery wywołania zadziałają, masz elementy potoku skryptowego. Zawiń zwykłe zapytanie w funkcję, uruchom pętlę strumieniową w kolejce i podłącz kolejkę do silnika syntezy mowy, którego wybierzesz. Silniki różnią się ceną, licencją i jakością, więc przeczytaj ich aktualne warunki. Ta usługa nie dostarcza jednego i nie mówi nic o nich.
Koszty pozostają małe, podczas gdy eksperymentujesz. Przy $0.15 za milion tokenów wejściowych i $0.50 za milion tokenów wyjściowych, typowe wywołanie demo kosztuje ułamek centa, a kredyt $0.50 pokrywa setki z nich. Zobacz stronę cenową dla doładowań od $20 do $500 z bonusami od 5% do 15%, płatne kryptowalutami. dokumentacja obejmuje pełną listę parametrów, limity zapytań (8 równoległych i 300 na minutę na pełnym kluczu) i kody błędów. Prompty nie są używane do trenowania.
Rozsądna kolejność na pierwsze popołudnie: uruchom zwykłe zapytanie, aż ton będzie odpowiedni, przełącz się na strumieniowanie i drukuj zdania po ich ukończeniu, a następnie dodaj albo wywoływanie funkcji, albo tryb JSON, w zależności od tego, jak Twój kod mowy chce otrzymywać dane. Przechowuj każdy prompt w pliku pod kontrolą wersji. Kiedy linia brzmi źle w końcowym audio, możesz ją wtedy prześledzić do dokładnej instrukcji, która ją wygenerowała, i zmienić jedną rzecz na raz.
Więcej przewodników
Pytania i odpowiedzi
Czy mogę posłuchać przykładowego głosu w tym demo?
Nie. API zwraca tylko tekst, JSON i wywoływania funkcji. Dostarczasz osobny silnik syntez mowy, który zamieni tekst na audio.
Jaki identyfikator modelu wysłać?
Wyślij uncensored jako wartość modelu, z bazowym URL https://api.xtts.cc/v1 i swoim kluczem w nagłówku Authorization: Bearer.
Czy demo działają na kluczu próbnym?
Tak. Klucz próbny pozwala na 2 równoległe żądania i 60 na minutę, co wystarczy na te przykłady. Uruchamiaj je po jednym.
Dlaczego otrzymuję odpowiedź 429?
Przekroczyłeś limit zapytań na minutę (rate_limited), miałeś zbyt wiele równoległych zapytań lub usługa była chwilowo przeciążona. Poczekaj na nagłówek Retry-After, jeśli jest podany, a następnie ponów zapytanie.
Twój klucz jest o jeden krok stąd
Utwórz konto, skopiuj klucz, zmień bazowy URL. To cała konfiguracja.