API de calibrare a marcajelor de timp ale versurilor
Acesta nu este recunoaștere vocală. Textul folosește întotdeauna versurile originale pe care le furnizezi; noi doar așezăm fiecare caracter la momentul corect — așa că nu apare niciodată «versuri deplasate din cauza caracterelor auzite greșit».
Descrierea endpoint-ului
Aliniază versuri existente la audio și returnează marcaje de timp pe rând și pe caracter, pentru evidențierea caracter cu caracter tip karaoke, versuri derulante și generarea de subtitrări.
Endpoint: POST /api/music/lyrics-align
Autentificare: vezi Autentificare; antetul este Authorization: Bearer YOUR_API_KEY
Facturare: per apel (momentan implicit 0,1 ¥ per apel); la o piesă de pe platformă cu separarea vocii bifată, se mai percepe o dată prețul platformei „separare voce/acompaniament". Suma efectiv debitată urmează configurația de prețuri din back-office.
Durată medie: 5–15 secunde (în funcție de lungimea audio-ului și de necesitatea separării vocii pe loc)
De ce e nevoie de calibrare: marcajele din partea de generare nu sunt întotdeauna exacte
API-ul de versuri cu marcaje de timp returnează direct marcajele cuvânt cu cuvânt din partea de generare, iar acestea au inexactități:
- repetițiile, armoniile dense, rap-ul și notele lungi derapează adesea în ansamblu sau deplasează caractere izolate;
- unele piese pierd un fragment la început (de exemplu o intro pură, cu primul fragment începând abia după cincisprezece secunde);
- unele rânduri sunt greu de ancorat la un moment clar.
Calibrarea reface alinierea temporală pe baza versurilor pe care le furnizezi tu: se corectează doar timpul, niciodată textul, ceea ce se potrivește cazurilor în care contează „se potrivește exact" (evidențiere pe caracter ca la KTV, subtitrări pe caracter, notare la cântat).
Abordare recomandată (trei pași, cele mai bune rezultate)
- Extrage mai întâi vocea (separare voce/acompaniament) și aliniază doar pista vocală — acompaniamentul și armoniile nu mai deranjează. Bază măsurată: într-o comparație rând cu rând „mix complet vs pistă vocală" a aceleiași piese, 5 din 28 de rânduri diferă cu peste 0,25 s (cel mai mult cu 2,64 s); două motoare independente diferă în medie cu 0,239 s pe pista vocală și cu 0,508 s pe mixul complet — aproape jumătate din concordanță. Așa că pentru evidențierea pe caracter (KTV/subtitrare) se recomandă activarea. (Câștigul exact se remăsoară cu motorul nou.)
- Furnizează versurile complete: toată piesa, rând cu rând, în corespondență unu-la-unu cu audio-ul. O frază sau o secțiune lipsă deplasează toate rândurile următoare; nu pune în versuri marcaje precum
[00:23.82](sunt ignorate automat). - La o piesă de pe platformă e suficient
vocal_separate: true, iar noi facem „separare + aliniere" într-un singur pas.
Trei moduri de utilizare
| Mod | Ce trimiți | De unde vin versurile | Separare vocală |
|---|---|---|---|
| Piesă externă · URL public | audio_url + versuri |
Le furnizezi tu | ❌ Neacceptat |
| Piesă externă · încărcare directă a unui fișier local (nou 2026-10) | audio_object_key + versuri |
Le furnizezi tu | ❌ Neacceptat |
| Piesă de pe platformă (generată pe acest site) | song_id |
Le luăm din înregistrarea piesei | ✅ Opțional |
Cum se leagă parametrii (aici se greșește cel mai des — citește cu atenție)
- Trimiți
song_id→ calea piesei de platformă: nu trimite șilyrics/audio_url/audio_object_key; - Trimiți
audio_urlsauaudio_object_key→ calea piesei externe: doar unul din cele două, și nu trimitesong_id; vocal_separatefuncționează doar la piesele de platformă; la o piesă externă este respins (audio-ul nu e la noi, nu poate fi separat).
Nou: încărcare directă a unui fișier local (audio-ul nu trece prin serverele noastre)
Folosește-o când audio-ul e pe mașina ta și nu vrei să îl urci mai întâi în spațiul tău public. Doi pași:
POST /api/music/lyrics-align/upload-ticketcufile_name/file_size/content_typeși primești unput_url(URL semnat, fără credențiale de durată) și unobject_key;- Fă
PUTcu fișierul laput_url, trimițândcontent_type-ul din răspuns exact așa cum este (face parte din semnătură; un caracter schimbat dă 403); - La trimiterea alinierii, dă
audio_object_keyîn loc deaudio_url.
Credențialul este de unică folosință: după ce alinierea se termină (reușit sau eșuat) serverul șterge obiectul, iar reutilizarea aceleiași chei dă eroare.
Nou: versurile au devenit opționale
Înainte, o piesă externă cerea versuri. Acum le poți omite: serverul face întâi o recunoaștere și folosește textul recunoscut ca versuri.
Compromisul trebuie spus clar: textul depinde atunci de rezultatul recunoașterii, deci unele caractere pot fi greșite. Astfel de răspunsuri sunt marcate cu
lyrics_source: "asr", confidence: "low" și, în warnings[],
{"code":"no_reference_lyrics"}.
Pentru evidențiere pe caracter / KTV, furnizează întotdeauna versurile originale.
Parametrii cererii
Headers
| Parametru | Tip | Obligatoriu | Observații |
|---|---|---|---|
| Authorization | string | da | Bearer YOUR_API_KEY |
| Content-Type | string | da | application/json |
Parametri din body
| Parametru | Tip | Obligatoriu | Implicit | Observații |
|---|---|---|---|---|
| song_id | string | unul din două | - | ID-ul piesei de platformă |
| lyrics | string | nu | - | Versurile originale, rânduri separate prin \n. Acum poate fi omis |
| audio_url | string | unul din două pentru extern | - | Adresa audio; trebuie să fie descărcabilă public |
| audio_object_key | string | unul din două pentru extern | - | Cheia obiectului încărcat direct (apelează întâi /lyrics-align/upload-ticket) |
| vocal_separate | boolean | nu | false |
Dacă se separă întâi vocea (doar piese de platformă) |
| language | string | nu | automat | Chinese / English etc.; fără valoare se deduce din versuri |
| granularity | string | nu | both |
both / line (fără ieșire pe caracter) / word |
| sections | string | nu | keep |
keep păstrează marcaje ca [Chorus] (nu intră în cronologie) / drop |
| format | string | nu | json |
json / lrc / lrc-word (ultimele două returnează și textele lrc și lrc_word) |
Limitări
| Element | Limită |
|---|---|
| Durata audio | ≤ 6 minute (mai mult returnează eroare și rambursare integrală) |
| Sursa audio | Trebuie să fie descărcabilă public; adresele care cer autentificare nu sunt acceptate |
| Formatul versurilor | Text simplu, rânduri cu \n; marcajele de secțiune ca [Verse] sau 【主歌】 rămân ca atare, dar nu intră în cronologie |
| Loturi | O piesă per apel; pentru mai multe fă singur o buclă |
| Salvarea rezultatului | Acest endpoint nu persistă nimic; salvează rezultatul singur |
Exemple de cerere
Piesă externă (versuri + adresa audio)
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": "Merg pe străzi reci\nBriza nopții îmi atinge ochii\nTimpul curge ca apa",
"audio_url": "https://your-bucket.example.com/song.mp3"
}'
Piesă de platformă (fără separare)
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"}'
Piesă de platformă + separare vocală (recomandat pentru 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}'
Răspuns
Răspuns de succes
{
"success": true,
"lyrics_source": "platform",
"vocal_separate": false,
"coverage": 0.935,
"exact": 196,
"fuzzy": 4,
"total": 214,
"lines": [
{
"text": "Merg pe străzi reci",
"start": 21.66,
"end": 24.06,
"chars": [
{"char": "M", "start": 21.66, "end": 21.74, "word": true},
{"char": "e", "start": 21.98, "end": 22.22, "word": true}
]
}
]
}
Descrierea câmpurilor
| Câmp | Tip | Observații |
|---|---|---|
success |
boolean | Dacă cererea a reușit |
lyrics_source |
string | platform = versuri din piesa de platformă; user = versuri furnizate de tine; asr = nu ai dat versuri, iar caracterele vin din recunoaștere |
vocal_separate |
boolean | Dacă de data aceasta s-a trecut prin separarea vocii |
confidence |
string | high / low (mereu low când lyrics_source=asr) |
warnings[] |
array | avertismente de degradare; fără versuri conține {"code":"no_reference_lyrics"} |
coverage |
number | Calitatea alinierii: proporția caracterelor cu ancoră temporală clară (0–1) |
exact / fuzzy / total |
number | caractere exacte / omofone / caractere valide din versuri |
lines[].text |
string | un rând de versuri, caracter cu caracter identic cu originalul tău |
lines[].start / end |
number | începutul și sfârșitul rândului (secunde) |
lines[].section |
boolean | dacă rândul este un marcaj de secțiune (true = fără timp, fără evidențiere) |
lines[].chars[] |
array | timpi pe caracter: char, start/end în secunde, word dacă intră în cronologie (punctuația este false) |
words[] |
array | listă plată pe caractere: text / start / end / line; nu se returnează la granularity=line |
lrc |
string | text LRC pe rânduri (doar la format=lrc sau lrc-word) |
lrc_word |
string | LRC pe caractere extins, cu etichete <mm:ss.xx> în rând (doar la format=lrc-word) |
Cum se folosește coverage (trei praguri)
| coverage | Utilizare recomandată |
|---|---|
| ≥ 0,9 | se poate face evidențiere pe caracter (karaoke) |
| 0,8 – 0,9 | amestec caracter și rând întreg, sau doar rânduri evidențiate, cu caracterul doar orientativ |
| < 0,8 | doar evidențiere pe rând (repetițiile, armoniile dense, dialectele și rap-ul ies des scăzute) |
Stare și durate
| Scenariu | Durată măsurată |
|---|---|
| Piesă de platformă · fără separare | circa 4,5 s |
| Piesă de platformă · separare (pista vocală există deja) | circa 11 s |
| Piesă de platformă · separare (necesară pe loc) | circa 25 s, până la circa 1 minut |
| Piesă externă · versuri + adresa audio | circa 5–15 s (în funcție de lungime) |
Limita unei singure execuții pe server este de 8 minute; setează timeout-ul clientului la 120 de secunde sau mai mult.
Răspunsuri de eroare
{
"success": false,
"message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
| Scenariu | Se percepe? |
|---|---|
| Lipsește audio-ul (niciunul din trei) | Nu (procesarea nu a început) |
audio_url și audio_object_key împreună |
Nu (procesarea nu a început) |
| Obiectul încărcat direct nu e încă acolo / a fost șters | Nu (procesarea nu a început) |
granularity / sections / format invalide |
Nu (procesarea nu a început) |
| Piesa de platformă nu există / nu aparține contului | Nu (procesarea nu a început) |
| Parametri lipsă sau invalizi | Nu (procesarea nu a început) |
| Audio peste limita de 6 minute | Rambursare integrală |
| Audio nedescărcabil (adresă nepublică / cere autentificare) | Rambursare integrală |
| Fără versuri și recunoașterea serverului a eșuat | Rambursare integrală |
| Separare vocală bifată dar fără pistă vocală utilizabilă | Rambursare integrală (inclusiv costul separării) |
| Eroare sau timeout al serviciului de aliniere | Rambursare integrală |
Principiu: fără rezultat final, rambursare integrală. Se percepe doar când marcajele pe caracter sunt chiar returnate, iar rambursarea e automată, fără cerere.
Facturare
| Element | Când se percepe | Observații |
|---|---|---|
| Calibrarea marcajelor de timp (bază) | la fiecare apel | per apel (momentan implicit 0,1 ¥); suma reală urmează configurația de prețuri din back-office |
| Supliment de transcriere | doar când nu furnizezi versuri | serverul trebuie să ruleze întâi o recunoaștere vocală, un cost pe care treapta „cu versuri" nu îl are, deci se tarifează separat |
| Separare vocală (opțional, doar piese de platformă) | când bifezi vocal_separate |
se percepe o dată la prețul actual „separare voce/acompaniament" și se decontează împreună cu acest endpoint |
Combinația:
de plată = preț de bază + (fără versuri ? supliment de transcriere : 0) + (separare bifată ? prețul separării : 0)
Costul separării vocale se percepe o singură dată: dacă ai separat deja piesa și pista vocală e disponibilă direct, îl percepe acest endpoint; dacă separarea trebuie făcută pe loc, îl percepe pasul de separare.
Exemplu complet (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("calitatea alinierii coverage =", res["coverage"])
for line in res["lines"]:
print(f'{line["start"]:7.2f} {line["text"]}')
# karaoke pe caractere: fiecare caracter din line["chars"] are propriul start / end
Întrebări frecvente
Î: Ieșirea e pe caracter sau pe rând?
R: Ambele. lines[].start este pe rând, lines[].chars[].start / end pe caracter; playerul ia ce are nevoie.
Î: De ce textul returnat este identic cu ce am trimis? R: Așa e proiectat. Nu recunoaștem și nu rescriem, doar aliniem timpul, așa că versurile nu pot fi „corectate într-o greșeală".
Î: coverage e mare dar tot sună ușor deplasat.
R: Eroarea pe caracter este de obicei de ordinul zecilor de milisecunde; dacă toată piesa e deplasată cu o valoare fixă, probabil există o tăcere la începutul audio-ului — taie-o și încearcă din nou.
Î: De ce separarea funcționa acum puțin timp și acum spune „pistă vocală indisponibilă"? R: Rezultatele separării sunt adrese temporare de scurtă durată (măsurat: expiră după circa o jumătate de oră). Atunci endpoint-ul încearcă să separe automat din nou; dacă tot eșuează, urmează rambursare integrală. Deci „separ acum, calibrez mai târziu" nu e fiabil: fă ambele în același flux.
Î: Trebuie să separ eu o piesă de platformă?
R: Nu. Cu vocal_separate: true verificăm dacă piesa are deja pistă vocală; dacă nu există una utilizabilă, dăm eroare și rambursăm, în loc să trimitem mixul complet.
Î: Se poate în loturi? R: O piesă per cerere. Pentru loturi, fă o buclă; fiecare apel se facturează normal, deci se recomandă cache local.
Î: Rezultatul se salvează? R: Acest endpoint nu persistă nimic; salvează singur valoarea returnată (marcajele pe rând și pe caracter sunt în răspuns).
Obține o cheie API
Creează o cheie API în consolă după înregistrare. Fiecare generare costă 0,6 ¥ și returnează 2 piese, descărcările sunt nelimitate și nu este nevoie de număr de telefon.
Obține cheia API Înapoi la prezentare