API di calibrazione dei timestamp del testo
Questo non è riconoscimento vocale. Il testo usa sempre il testo originale che fornisci tu; noi mettiamo solo ogni carattere nell'istante giusto — quindi non capita mai che «caratteri sentiti male disallineino il testo».
Descrizione dell'endpoint
Allinea un testo esistente a un audio e restituisce timestamp per riga e per carattere, per l'evidenziazione carattere per carattere tipo karaoke, il testo che scorre e la generazione di sottotitoli.
Endpoint: POST /api/music/lyrics-align
Autenticazione: vedi Autenticazione; l'header è Authorization: Bearer YOUR_API_KEY
Fatturazione: a chiamata (attualmente 0,1 ¥ per chiamata per impostazione predefinita); su un brano della piattaforma con separazione della voce spuntata, viene addebitato una volta in più il prezzo «separazione voce/base» della piattaforma. L'importo effettivo segue la configurazione prezzi del back-office.
Tempo medio: 5–15 secondi (dipende dalla durata dell'audio e dalla necessità di separare la voce sul momento)
Perché serve la calibrazione: i timestamp del lato generazione non sono sempre precisi
L'API di testi con timestamp restituisce direttamente i timestamp parola per parola del lato generazione e presentano imprecisioni:
- ripetizioni, armonie dense, rap e note lunghe tendono a slittare nel complesso o a spostare singoli caratteri;
- alcuni brani perdono un tratto all'inizio (per esempio un'intro pura, con il primo frammento che parte solo dopo i quindici secondi);
- alcune righe sono difficili da ancorare a un istante chiaro.
La calibrazione rifà l'allineamento temporale sul testo che fornisci tu: si corregge solo il tempo, mai il testo, il che serve ai casi in cui conta «se combacia» (evidenziazione per carattere tipo KTV, sottotitoli per carattere, valutazione del canto).
Approccio consigliato (tre passi, risultato migliore)
- Estrai prima la voce (separazione voce/base) e allinea solo la traccia vocale — base e armonie smettono di disturbare. Base misurata: in un confronto riga per riga «mix completo vs traccia vocale» dello stesso brano, 5 righe su 28 differivano di oltre 0,25 s (la maggiore, 2,64 s); due motori indipendenti differivano in media di 0,239 s sulla traccia vocale e di 0,508 s sul mix completo — quasi la metà della concordanza. Per l'evidenziazione per carattere (KTV/sottotitoli) conviene quindi attivarla. (Il guadagno esatto è in corso di nuova misura con il motore nuovo.)
- Fornisci il testo completo: tutto il brano, riga per riga, in corrispondenza uno a uno con l'audio. Una frase o una sezione mancante sposta tutte le righe successive; non inserire timestamp come
[00:23.82]nel testo (vengono ignorati automaticamente). - Su un brano della piattaforma basta spuntare
vocal_separate: truee facciamo «separazione + allineamento» in un solo passo.
Tre modi di usarla
| Uso | Cosa invii | Da dove viene il testo | Separazione della voce |
|---|---|---|---|
| Brano esterno · URL pubblico | audio_url + testo |
Lo fornisci tu | ❌ Non supportato |
| Brano esterno · invio diretto di un file locale (novità 2026-10) | audio_object_key + testo |
Lo fornisci tu | ❌ Non supportato |
| Brano della piattaforma (generato su questo sito) | song_id |
Lo prendiamo dal record del brano | ✅ Opzionale |
Come sono legati i parametri (è qui che si sbaglia di più: leggi con attenzione)
- Inviare
song_id→ percorso brano della piattaforma: non inviare anchelyrics/audio_url/audio_object_key; - Inviare
audio_urloaudio_object_key→ percorso brano esterno: solo uno dei due e non inviaresong_id; vocal_separatefunziona solo sui brani della piattaforma; su un brano esterno viene rifiutato (l'audio non è dalla nostra parte, non si può separare).
Novità: invio diretto di un file locale (l'audio non passa dai nostri server)
Usalo quando l'audio è sulla tua macchina e preferisci non caricarlo prima nel tuo spazio pubblico. Due passi:
POST /api/music/lyrics-align/upload-ticketconfile_name/file_size/content_typee ricevi unaput_url(URL firmato, senza credenziali di lunga durata) e unobject_key;- Fai un
PUTdel file suput_url, portando ilcontent_typedella risposta così com'è (partecipa alla firma; un carattere cambiato dà 403); - All'invio dell'allineamento, manda
audio_object_keyinvece diaudio_url.
La credenziale è monouso: finito l'allineamento (successo o errore) il server cancella l'oggetto e riusare la stessa chiave dà errore.
Novità: il testo è diventato opzionale
Prima un brano esterno richiedeva il testo. Ora puoi ometterlo: il server esegue un riconoscimento e usa il testo riconosciuto come testo del brano.
Il compromesso va detto chiaramente: il testo dipende dal risultato del riconoscimento, quindi qualche carattere può essere sbagliato. Queste risposte sono marcate con
lyrics_source: "asr", confidence: "low" e, in warnings[],
{"code":"no_reference_lyrics"}.
Per l'evidenziazione per carattere / KTV, fornisci sempre il testo originale.
Parametri della richiesta
Headers
| Parametro | Tipo | Obbligatorio | Note |
|---|---|---|---|
| Authorization | string | sì | Bearer YOUR_API_KEY |
| Content-Type | string | sì | application/json |
Parametri del body
| Parametro | Tipo | Obbligatorio | Predefinito | Note |
|---|---|---|---|---|
| song_id | string | uno dei due | - | ID del brano della piattaforma |
| lyrics | string | no | - | Testo originale, righe separate da \n. Ora può essere omesso |
| audio_url | string | uno dei due per l'esterno | - | Indirizzo audio; deve essere scaricabile pubblicamente |
| audio_object_key | string | uno dei due per l'esterno | - | Chiave dell'oggetto inviato direttamente (chiama prima /lyrics-align/upload-ticket) |
| vocal_separate | boolean | no | false |
Se separare prima la voce (solo brani della piattaforma) |
| language | string | no | automatico | Chinese / English ecc.; se assente viene dedotta dal testo |
| granularity | string | no | both |
both / line (nessun output per carattere) / word |
| sections | string | no | keep |
keep conserva marcatori come [Chorus] (non entrano nella timeline) / drop |
| format | string | no | json |
json / lrc / lrc-word (gli ultimi due restituiscono anche i testi lrc e lrc_word) |
Limiti
| Voce | Limite |
|---|---|
| Durata audio | ≤ 6 minuti (oltre, errore e rimborso totale) |
| Origine audio | Deve essere scaricabile pubblicamente; gli indirizzi che richiedono una sessione non sono accettati |
| Formato del testo | Testo semplice, righe con \n; i marcatori di sezione come [Verse] o 【主歌】 restano com'è ma non entrano nella timeline |
| Lotti | Un brano per chiamata; per più brani fai tu un ciclo |
| Salvataggio del risultato | Questo endpoint non persiste nulla; salva tu il risultato |
Esempi di richiesta
Brano esterno (testo + indirizzo 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": "Cammino per strade fredde\nLa brezza notturna sfiora i miei occhi\nIl tempo scorre come l'\''acqua",
"audio_url": "https://your-bucket.example.com/song.mp3"
}'
Brano della piattaforma (senza separazione)
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"}'
Brano della piattaforma + separazione della voce (consigliato per il 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}'
Risposta
Risposta di successo
{
"success": true,
"lyrics_source": "platform",
"vocal_separate": false,
"coverage": 0.935,
"exact": 196,
"fuzzy": 4,
"total": 214,
"lines": [
{
"text": "Cammino per strade fredde",
"start": 21.66,
"end": 24.06,
"chars": [
{"char": "C", "start": 21.66, "end": 21.74, "word": true},
{"char": "a", "start": 21.98, "end": 22.22, "word": true}
]
}
]
}
Riferimento dei campi
| Campo | Tipo | Note |
|---|---|---|
success |
boolean | Se la richiesta è riuscita |
lyrics_source |
string | platform = testo preso dal brano della piattaforma; user = testo fornito da te; asr = non hai dato il testo e i caratteri vengono dal riconoscimento |
vocal_separate |
boolean | Se questa volta è passato dalla separazione della voce |
confidence |
string | high / low (sempre low quando lyrics_source=asr) |
warnings[] |
array | Avvisi di degrado; senza testo contiene {"code":"no_reference_lyrics"} |
coverage |
number | Qualità dell'allineamento: quota di caratteri con ancora temporale chiara (0–1) |
exact / fuzzy / total |
number | caratteri esatti / omofoni / caratteri validi del testo |
lines[].text |
string | Una riga di testo, carattere per carattere identica al tuo originale |
lines[].start / end |
number | inizio e fine della riga (secondi) |
lines[].section |
boolean | se la riga è un marcatore di sezione (true = nessun tempo, nessuna evidenziazione) |
lines[].chars[] |
array | tempi per carattere: char, start/end in secondi, word se entra nella timeline (la punteggiatura è false) |
words[] |
array | elenco piatto per carattere: text / start / end / line; non restituito con granularity=line |
lrc |
string | testo LRC per riga (solo con format=lrc o lrc-word) |
lrc_word |
string | LRC per carattere esteso, con tag <mm:ss.xx> in riga (solo con format=lrc-word) |
Come usare coverage (tre fasce)
| coverage | Uso consigliato |
|---|---|
| ≥ 0,9 | si può fare l'evidenziazione per carattere (karaoke) |
| 0,8 – 0,9 | misto per carattere e per riga, oppure evidenzia solo le righe e usa il carattere come riferimento |
| < 0,8 | solo evidenziazione per riga (ripetizioni, armonie dense, dialetti e rap tendono a uscire bassi) |
Stato e tempi
| Scenario | Tempo misurato |
|---|---|
| Brano della piattaforma · senza separazione | circa 4,5 s |
| Brano della piattaforma · separazione (traccia vocale già presente) | circa 11 s |
| Brano della piattaforma · separazione (da fare sul momento) | circa 25 s, fino a circa 1 minuto |
| Brano esterno · testo + indirizzo audio | circa 5–15 s (secondo la durata) |
Il limite di una singola esecuzione sul server è 8 minuti; imposta il timeout del client a 120 secondi o più.
Risposte di errore
{
"success": false,
"message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
| Scenario | Si addebita? |
|---|---|
| Manca l'audio (nessuno dei tre) | Nessun addebito (elaborazione non avviata) |
audio_url e audio_object_key insieme |
Nessun addebito (elaborazione non avviata) |
| L'oggetto inviato direttamente non c'è ancora / è stato eliminato | Nessun addebito (elaborazione non avviata) |
granularity / sections / format non validi |
Nessun addebito (elaborazione non avviata) |
| Il brano della piattaforma non esiste / non è dell'account | Nessun addebito (elaborazione non avviata) |
| Parametri mancanti o non validi | Nessun addebito (elaborazione non avviata) |
| Audio oltre il limite di 6 minuti | Rimborso totale |
| Audio non scaricabile (indirizzo non pubblico / richiede login) | Rimborso totale |
| Testo non fornito e riconoscimento lato server fallito | Rimborso totale |
| Separazione spuntata ma nessuna traccia vocale utilizzabile | Rimborso totale (incluso il costo della separazione) |
| Errore o timeout del servizio di allineamento | Rimborso totale |
Principio: senza risultato finale, rimborso totale. Si addebita solo quando i timestamp per carattere vengono davvero restituiti, e il rimborso è automatico, senza richiesta.
Fatturazione
| Voce | Quando si addebita | Note |
|---|---|---|
| Calibrazione dei timestamp (base) | a ogni chiamata | a chiamata (attualmente 0,1 ¥ per chiamata per impostazione predefinita); l'importo effettivo segue la configurazione prezzi del back-office |
| Supplemento di trascrizione | solo se non fornisci il testo | il server deve prima eseguire un riconoscimento vocale, un costo che la fascia «con testo» non ha, quindi è prezzato a parte |
| Separazione della voce (opzionale, solo brani della piattaforma) | quando spunti vocal_separate |
addebitata una volta al prezzo attuale di «separazione voce/base» e regolata insieme a questo endpoint |
La combinazione:
da pagare = prezzo base + (testo non fornito ? supplemento di trascrizione : 0) + (separazione spuntata ? prezzo separazione : 0)
La separazione della voce si addebita una sola volta: se hai già separato e la traccia vocale è disponibile, la addebita questo endpoint; se la separazione serve sul momento, la addebita lo step di separazione.
Esempio completo (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("qualità dell'allineamento coverage =", res["coverage"])
for line in res["lines"]:
print(f'{line["start"]:7.2f} {line["text"]}')
# karaoke per carattere: ogni carattere in line["chars"] ha il suo start / end
Domande frequenti
D: L'output è per carattere o per riga?
R: Entrambi. lines[].start è per riga, lines[].chars[].start / end per carattere; il player prende quello che serve.
D: Perché il testo restituito è identico a quello che ho inviato? R: È il progetto. Non riconosciamo né riscriviamo, allineiamo solo i tempi, quindi il testo non può mai essere «corretto in refuso».
D: Il coverage è alto ma suona ancora un po' spostato.
R: L'errore per carattere è di solito nell'ordine di decine di millisecondi; se tutto il brano è spostato di un valore fisso, molto probabilmente c'è un tratto di silenzio all'inizio dell'audio: taglialo e riprova.
D: Perché poco fa la separazione andava e ora dice «traccia vocale non disponibile»? R: I risultati della separazione sono indirizzi temporanei di breve durata (misurato: scadono dopo circa mezz'ora). In quel caso l'endpoint prova a separare di nuovo; se fallisce ancora, c'è rimborso totale. Quindi «separo adesso e calibro dopo» non è affidabile: fai le due cose nello stesso flusso.
D: Devo separare io un brano della piattaforma?
R: No. Con vocal_separate: true controlliamo se il brano ha già una traccia vocale; se non ce n'è una utilizzabile, diamo errore e rimborso invece di rifilare il mix completo.
D: Si possono fare lotti? R: Un brano per richiesta. Per i lotti fai un ciclo; ogni chiamata viene addebitata normalmente, quindi conviene mettere i risultati in cache.
D: Il risultato viene salvato? R: Questo endpoint non persiste nulla; salva tu il valore restituito (i timestamp per riga e per carattere sono nella risposta).
Ottenere una chiave API
Dopo la registrazione puoi creare una chiave API nella console. Ogni generazione costa 0,6 ¥ e restituisce 2 brani, i download sono illimitati e non serve un numero di telefono.
Ottieni chiave API Torna alla panoramica