API di calibrazione dei timestamp del testo

Aggiornato il 2026-09-18 · team Suno-API

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:

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)

  1. 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.)
  2. 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).
  3. Su un brano della piattaforma basta spuntare vocal_separate: true e 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)

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:

  1. POST /api/music/lyrics-align/upload-ticket con file_name / file_size / content_type e ricevi una put_url (URL firmato, senza credenziali di lunga durata) e un object_key;
  2. Fai un PUT del file su put_url, portando il content_type della risposta così com'è (partecipa alla firma; un carattere cambiato dà 403);
  3. All'invio dell'allineamento, manda audio_object_key invece di audio_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).

AvantiAPI del certificato di licenza commerciale musicale

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