API kalibracji znaczników czasu tekstu
To nie jest rozpoznawanie mowy. Tekst zawsze pochodzi z oryginalnego tekstu, który podajesz; my tylko umieszczamy każdy znak w odpowiednim momencie — więc „przesunięcie tekstu przez źle usłyszane znaki" nie występuje.
Opis punktu końcowego
Wyrównuje istniejący tekst do dźwięku i zwraca znaczniki czasu dla wiersza i dla znaku — do podświetlania znak po znaku w stylu karaoke, przewijania tekstu i generowania napisów.
Punkt końcowy: POST /api/music/lyrics-align
Uwierzytelnianie: zobacz Uwierzytelnianie; nagłówek to Authorization: Bearer YOUR_API_KEY
Rozliczenie: za wywołanie (obecnie domyślnie 0,1 juana za wywołanie); jeśli w utworze platformy zaznaczono separację wokalu, dodatkowo naliczana jest raz cena platformy „rozdzielanie wokalu/podkładu". Faktycznie pobierana kwota zależy od konfiguracji cen w panelu administracyjnym.
Średni czas: 5–15 sekund (zależnie od długości dźwięku i od tego, czy wokal trzeba rozdzielić na miejscu)
Dlaczego kalibracja jest potrzebna: znaczniki po stronie generowania nie zawsze są dokładne
API tekstu ze znacznikami czasu zwraca znaczniki słowo po słowie prosto ze strony generowania i są one niedokładne:
- powtórzenia, gęste harmonie, rap i długie dźwięki często przesuwają się całościowo albo przesuwają pojedyncze znaki;
- niektórym utworom brakuje fragmentu na początku (np. czyste intro, a pierwszy fragment zaczyna się dopiero w kilkunastej sekundzie);
- niektóre wiersze trudno przypiąć do wyraźnego punktu w czasie.
Kalibracja robi wyrównanie czasowe od nowa na podstawie podanego przez Ciebie tekstu: korygowany jest tylko czas, nigdy tekst — to pasuje do przypadków, w których liczy się „czy się zgadza" (podświetlanie znak po znaku jak w KTV, napisy po znaku, ocena śpiewania).
Zalecany sposób (trzy kroki, najlepszy efekt)
- Najpierw wyodrębnij wokal (rozdzielanie wokalu/podkładu) i wyrównuj tylko ścieżkę wokalu — podkład i harmonie przestają przeszkadzać. Podstawa z pomiarów: w porównaniu wiersz po wierszu „pełny miks vs ścieżka wokalu" tego samego utworu 5 z 28 wierszy różniło się o ponad 0,25 s (największe o 2,64 s); dwa niezależne silniki różniły się średnio o 0,239 s na ścieżce wokalu i o 0,508 s na pełnym miksie — zgodność niemal o połowę gorsza. Dlatego do podświetlania po znakach (KTV/napisy) warto to włączyć. (Dokładny zysk jest właśnie mierzony ponownie na nowym silniku.)
- Podaj pełny tekst: cały utwór, wiersz po wierszu, jeden do jednego z dźwiękiem. Brakująca fraza lub sekcja przesuwa wszystkie kolejne wiersze; nie wpisuj w tekst znaczników typu
[00:23.82](są automatycznie ignorowane). - W utworze platformy wystarczy
vocal_separate: true, a my zrobimy „rozdzielenie + wyrównanie" w jednym kroku.
Trzy sposoby użycia
| Sposób | Co wysyłasz | Skąd tekst | Separacja wokalu |
|---|---|---|---|
| Utwór zewnętrzny · publiczny URL | audio_url + tekst |
Podajesz sam | ❌ Nieobsługiwane |
| Utwór zewnętrzny · bezpośrednie przesłanie pliku lokalnego (nowość 2026-10) | audio_object_key + tekst |
Podajesz sam | ❌ Nieobsługiwane |
| Utwór platformy (wygenerowany na tej stronie) | song_id |
Bierzemy z rekordu utworu | ✅ Opcjonalnie |
Jak wiążą się parametry (tu najczęściej się myli — przeczytaj uważnie)
- Wysyłasz
song_id→ ścieżka utworu platformy: nie wysyłaj dodatkowolyrics/audio_url/audio_object_key; - Wysyłasz
audio_urlalboaudio_object_key→ ścieżka utworu zewnętrznego: tylko jedno z dwóch, i nie wysyłajsong_id; vocal_separatedziała tylko w utworach platformy; w utworze zewnętrznym zostanie odrzucone (dźwięk nie jest u nas, nie da się rozdzielić).
Nowość: bezpośrednie przesłanie pliku lokalnego (dźwięk nie przechodzi przez nasze serwery)
Użyj tego, gdy dźwięk jest na Twojej maszynie, a nie chcesz najpierw wrzucać go do własnego publicznego magazynu. Dwa kroki:
POST /api/music/lyrics-align/upload-ticketzfile_name/file_size/content_typei otrzymujeszput_url(podpisany URL bez długoterminowych poświadczeń) orazobject_key;- Wyślij plik metodą
PUTnaput_url, przekazująccontent_typez odpowiedzi dokładnie taki, jaki jest (bierze udział w podpisie; jeden zmieniony znak to 403); - Przy wysyłaniu wyrównania podaj
audio_object_keyzamiastaudio_url.
Poświadczenie jest jednorazowe: po zakończeniu wyrównania (sukces lub błąd) serwer usuwa obiekt, a ponowne użycie tego samego klucza daje błąd.
Nowość: tekst stał się opcjonalny
Wcześniej utwór zewnętrzny wymagał tekstu. Teraz możesz go pominąć: serwer najpierw wykonuje rozpoznanie i używa rozpoznanego tekstu jako tekstu utworu.
Trzeba to powiedzieć wprost: tekst zależy wtedy od wyniku rozpoznania, więc pojedyncze znaki mogą być błędne. Takie odpowiedzi są oznaczone
lyrics_source: "asr", confidence: "low" oraz w warnings[]
{"code":"no_reference_lyrics"}.
Do podświetlania po znakach / KTV zawsze podawaj oryginalny tekst.
Parametry żądania
Headers
| Parametr | Typ | Wymagany | Uwagi |
|---|---|---|---|
| Authorization | string | tak | Bearer YOUR_API_KEY |
| Content-Type | string | tak | application/json |
Parametry treści
| Parametr | Typ | Wymagany | Domyślnie | Uwagi |
|---|---|---|---|---|
| song_id | string | jedno z dwóch | - | ID utworu platformy |
| lyrics | string | nie | - | Oryginalny tekst, wiersze rozdzielone \n. Można teraz pominąć |
| audio_url | string | jedno z dwóch dla zewnętrznych | - | Adres dźwięku; musi być publicznie pobieralny |
| audio_object_key | string | jedno z dwóch dla zewnętrznych | - | Klucz obiektu przesłanego bezpośrednio (najpierw wywołaj /lyrics-align/upload-ticket) |
| vocal_separate | boolean | nie | false |
Czy najpierw rozdzielić wokal (tylko utwory platformy) |
| language | string | nie | automatycznie | Chinese / English itd.; bez wartości zgadywane z tekstu |
| granularity | string | nie | both |
both / line (bez wyjścia po znakach) / word |
| sections | string | nie | keep |
keep zachowuje znaczniki typu [Chorus] (nie wchodzą do osi czasu) / drop |
| format | string | nie | json |
json / lrc / lrc-word (dwa ostatnie zwracają też tekst lrc i lrc_word) |
Ograniczenia
| Pozycja | Ograniczenie |
|---|---|
| Długość dźwięku | ≤ 6 minut (powyżej zwracany błąd i pełny zwrot) |
| Źródło dźwięku | Musi być publicznie pobieralne; adresy wymagające zalogowania nie są przyjmowane |
| Format tekstu | Zwykły tekst, wiersze \n; znaczniki sekcji typu [Verse] czy 【主歌】 są zachowane, ale nie wchodzą do osi czasu |
| Partie | Jeden utwór na wywołanie; dla wielu sam rób pętlę |
| Zapis wyniku | Ten punkt końcowy nic nie zapisuje; zachowaj wynik samodzielnie |
Przykłady żądania
Utwór zewnętrzny (tekst + adres dźwięku)
curl -X POST https://www.suno-api.io/api/music/lyrics-align \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"lyrics": "Idę wśród chłodnych ulic\nNocny wiatr muska moje oczy\nCzas płynie jak woda",
"audio_url": "https://your-bucket.example.com/song.mp3"
}'
Utwór platformy (bez rozdzielania)
curl -X POST https://www.suno-api.io/api/music/lyrics-align \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_id": "17e52af7-b5df-4877-a98a-dce94e0e6aa2"}'
Utwór platformy + separacja wokalu (zalecane do karaoke)
curl -X POST https://www.suno-api.io/api/music/lyrics-align \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"song_id": "17e52af7-b5df-4877-a98a-dce94e0e6aa2", "vocal_separate": true}'
Odpowiedź
Odpowiedź sukcesu
{
"success": true,
"lyrics_source": "platform",
"vocal_separate": false,
"coverage": 0.935,
"exact": 196,
"fuzzy": 4,
"total": 214,
"lines": [
{
"text": "Idę wśród chłodnych ulic",
"start": 21.66,
"end": 24.06,
"chars": [
{"char": "I", "start": 21.66, "end": 21.74, "word": true},
{"char": "d", "start": 21.98, "end": 22.22, "word": true}
]
}
]
}
Opis pól
| Pole | Typ | Uwagi |
|---|---|---|
success |
boolean | Czy żądanie się powiodło |
lyrics_source |
string | platform = tekst z utworu platformy; user = tekst podany przez Ciebie; asr = nie podałeś tekstu i znaki pochodzą z rozpoznania |
vocal_separate |
boolean | Czy tym razem przeszło przez separację wokalu |
confidence |
string | high / low (przy lyrics_source=asr zawsze low) |
warnings[] |
array | Ostrzeżenia o degradacji; bez tekstu zawiera {"code":"no_reference_lyrics"} |
coverage |
number | Jakość wyrównania: udział znaków z wyraźnym punktem czasu (0–1) |
exact / fuzzy / total |
number | znaki dokładne / homofoniczne / istotne znaki tekstu |
lines[].text |
string | jeden wiersz tekstu, znak w znak równy Twojemu oryginałowi |
lines[].start / end |
number | początek i koniec wiersza (sekundy) |
lines[].section |
boolean | czy wiersz jest znacznikiem sekcji (true = bez czasu, bez podświetlania) |
lines[].chars[] |
array | czasy znaków: char, start/end w sekundach, word czy wchodzi do osi czasu (interpunkcja to false) |
words[] |
array | płaska lista znaków: text / start / end / line; nie zwracana przy granularity=line |
lrc |
string | tekst LRC wiersz po wierszu (tylko przy format=lrc lub lrc-word) |
lrc_word |
string | rozszerzony LRC znakowy ze znacznikami <mm:ss.xx> w wierszu (tylko przy format=lrc-word) |
Jak używać coverage (trzy progi)
| coverage | Zalecane użycie |
|---|---|
| ≥ 0,9 | można podświetlać znak po znaku (karaoke) |
| 0,8 – 0,9 | mieszaj znaki i całe wiersze albo podświetlaj tylko wiersze, a znaki traktuj poglądowo |
| < 0,8 | tylko podświetlanie wierszy (powtórzenia, gęste harmonie, dialekty i rap wypadają nisko) |
Stan i czasy
| Scenariusz | Zmierzony czas |
|---|---|
| Utwór platformy · bez rozdzielania | ok. 4,5 s |
| Utwór platformy · rozdzielanie (ścieżka wokalu już jest) | ok. 11 s |
| Utwór platformy · rozdzielanie (trzeba rozdzielić na miejscu) | ok. 25 s, maksymalnie ok. 1 minuty |
| Utwór zewnętrzny · tekst + adres dźwięku | ok. 5–15 s (zależnie od długości) |
Limit jednego przebiegu na serwerze to 8 minut; ustaw limit czasu klienta na 120 sekund lub więcej.
Odpowiedzi błędów
{
"success": false,
"message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
| Scenariusz | Czy pobierana opłata? |
|---|---|
| Brak dźwięku (żadne z trzech) | Nie (przetwarzanie nie ruszyło) |
audio_url i audio_object_key razem |
Nie (przetwarzanie nie ruszyło) |
| Obiekt przesłany bezpośrednio jeszcze nie ma / został usunięty | Nie (przetwarzanie nie ruszyło) |
Niepoprawne granularity / sections / format |
Nie (przetwarzanie nie ruszyło) |
| Utwór platformy nie istnieje / nie należy do konta | Nie (przetwarzanie nie ruszyło) |
| Brakujące lub niepoprawne parametry | Nie (przetwarzanie nie ruszyło) |
| Dźwięk dłuższy niż limit 6 minut | Pełny zwrot |
| Dźwięku nie da się pobrać (adres niepubliczny / wymaga logowania) | Pełny zwrot |
| Brak tekstu i rozpoznanie po stronie serwera się nie powiodło | Pełny zwrot |
| Zaznaczono separację wokalu, ale brak użytecznej ścieżki wokalu | Pełny zwrot (wraz z opłatą za separację) |
| Awaria lub limit czasu usługi wyrównywania | Pełny zwrot |
Zasada: brak wyniku końcowego to pełny zwrot. Opłata jest pobierana tylko wtedy, gdy znaczniki znaków naprawdę wrócą, a zwrot jest automatyczny, bez wniosku.
Rozliczenie
| Pozycja | Kiedy naliczane | Uwagi |
|---|---|---|
| Kalibracja znaczników tekstu (baza) | przy każdym wywołaniu | za wywołanie (obecnie domyślnie 0,1 juana); faktyczna kwota zależy od konfiguracji cen w panelu administracyjnym |
| Dopłata za transkrypcję | tylko gdy nie podasz tekstu | serwer musi najpierw uruchomić rozpoznawanie mowy — koszt, którego próg „z tekstem" nie ma, dlatego wyceniany osobno |
| Separacja wokalu (opcjonalna, tylko utwory platformy) | gdy zaznaczysz vocal_separate |
naliczana raz po obecnej cenie „rozdzielanie wokalu/podkładu" i rozliczana razem z tym punktem końcowym |
Złożenie:
do zapłaty = cena bazowa + (brak tekstu ? dopłata za transkrypcję : 0) + (zaznaczona separacja ? cena separacji : 0)
Opłata za separację wokalu jest pobierana tylko raz: jeśli utwór jest już rozdzielony i ścieżka wokalu jest dostępna, pobiera ją ten punkt końcowy; jeśli trzeba rozdzielać na miejscu, pobiera ją krok separacji.
Pełny przykład (Python)
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://www.suno-api.io"
def align_lyrics(song_id=None, lyrics=None, audio_url=None, vocal_separate=False):
payload = {}
if song_id:
payload["song_id"] = song_id
payload["vocal_separate"] = vocal_separate
else:
payload["lyrics"] = lyrics
payload["audio_url"] = audio_url
r = requests.post(
f"{BASE}/api/music/lyrics-align",
headers={"Authorization": f"Bearer {API_KEY}"},
json=payload,
timeout=600,
)
data = r.json()
if not data.get("success"):
raise RuntimeError(data.get("message"))
return data
res = align_lyrics(song_id="17e52af7-b5df-4877-a98a-dce94e0e6aa2", vocal_separate=True)
print("jakość wyrównania coverage =", res["coverage"])
for line in res["lines"]:
print(f'{line["start"]:7.2f} {line["text"]}')
# karaoke znak po znaku: każdy znak w line["chars"] ma własne start / end
Częste pytania
P: Wynik jest po znaku czy po wierszu?
O: Jedno i drugie. lines[].start to poziom wiersza, lines[].chars[].start / end to poziom znaku; odtwarzacz bierze, co potrzebuje.
P: Dlaczego zwrócony tekst jest identyczny z wysłanym? O: Tak to zaprojektowano. Nie rozpoznajemy i nie przepisujemy, tylko wyrównujemy czas, więc tekst nigdy nie „zamieni się w literówkę".
P: coverage jest wysoki, a mimo to brzmi trochę przesunięte.
O: Błąd po znaku to zwykle dziesiątki milisekund; jeśli cały utwór jest przesunięty o stałą wartość, najpewniej na początku dźwięku jest cisza — przytnij ją i spróbuj ponownie.
P: Dlaczego przed chwilą separacja działała, a teraz komunikat „ścieżka wokalu niedostępna"? O: Wyniki separacji to krótkotrwałe adresy tymczasowe (z pomiarów: wygasają po około pół godzinie). Wtedy punkt końcowy próbuje rozdzielić ponownie; jeśli nadal się nie uda, jest pełny zwrot. Czyli „rozdziel teraz, kalibruj później" jest zawodne — rób oba kroki w jednym przepływie.
P: Czy muszę sam rozdzielać utwór platformy?
O: Nie. Przy vocal_separate: true sprawdzamy, czy utwór ma już ścieżkę wokalu; jeśli nie ma użytecznej, zwracamy błąd i pieniądze, a nie podsuwamy pełnego miksu.
P: Da się partiami? O: Jeden utwór na żądanie. Dla partii rób pętlę; każde wywołanie jest normalnie rozliczane, więc warto cache'ować wyniki.
P: Czy wynik jest zapisywany? O: Ten punkt końcowy nic nie zapisuje; zachowaj zwróconą wartość samodzielnie (znaczniki wierszy i znaków są w odpowiedzi).
Uzyskaj klucz API
Po rejestracji utwórz klucz API w konsoli. Każde generowanie kosztuje 0,6 ¥ i zwraca 2 utwory, pobierania są nieograniczone, a numer telefonu nie jest wymagany.
Pobierz klucz API Powrót do przeglądu