歌詞時間戳校正 API

2026-09-18 更新 · Suno-API 團隊

這不是語音辨識。 文字永遠採用你給的歌詞原文,我們只負責把每個字放到正確的時間點上——所以不會出現「辨識錯字導致歌詞對不上」的情況。

介面說明

把已有的歌詞和音訊對齊,輸出逐行 + 逐字的時間戳,用於卡拉OK逐字高亮、滾動歌詞、字幕生成。

介面位址:POST /api/music/lyrics-align

驗證:見認證說明,請求標頭 Authorization: Bearer YOUR_API_KEY

計費:按次計費(目前預設 0.1 元/次);平台歌曲勾選人聲分離時,另按平台「人聲/伴奏分離」價格計一次。實際扣費以目前後台價格設定為準。

平均耗時:5–15 秒(視音訊長度、以及是否需要現場做人聲分離而定)

為什麼需要校正:生成側的時間戳並不總是準

時間軸歌詞 API 直接回傳生成側的逐詞時間戳,存在不準確性:

歌詞時間戳校正是在你自己提供的歌詞基礎上重新做時間對齊:只校正時間,不改文字,適合對「能不能對上」要求高的場景(KTV 逐字高亮、逐字字幕、跟唱評分)。

建議做法(三步,效果最好)

  1. 先提取純人聲(人聲/伴奏分離),只把人聲軌拿去對齊——伴奏與和聲不再干擾。 實測依據:同一首歌的「全曲 vs 人聲軌」逐行對比裡,28 行有 5 行差異超過 0.25 秒(最大 2.64 秒); 兩個互相獨立的引擎在人聲軌上的平均差 0.239 秒、在全曲上 0.508 秒——一致度幾乎差一倍。 所以做逐字高亮(KTV/字幕)建議開啟。(具體提升幅度正在用新引擎重新測。)
  2. 提供完整歌詞:整首歌、按行、和音訊一一對應。漏句或段落缺失會讓後面的行整體錯位;歌詞裡不要帶 [00:23.82] 這類時間戳(帶了會自動忽略)。
  3. 平台歌曲可以直接勾 vocal_separate: true,由我們一步完成「分離 + 對齊」。

三種用法

用法 傳什麼 歌詞從哪來 支援人聲分離
外部歌曲 · 公網位址 audio_url + 歌詞 你自己提供 ❌ 不支援
外部歌曲 · 本機檔案直傳(2026-10 新增) audio_object_key + 歌詞 你自己提供 ❌ 不支援
平台歌曲(本站生成的歌) song_id 我們從歌曲記錄裡取 ✅ 可選

參數的關係(最容易搞錯,務必看清)

新增:本機檔案直傳(音訊不經過我們的伺服器)

音訊在你本機、又不想先傳到自己的公網儲存時用這個。兩步:

  1. POST /api/music/lyrics-align/upload-ticket,帶 file_name / file_size / content_type, 拿到 put_url(簽名 URL,不含任何長期憑證)與 object_key;
  2. 把檔案 PUT 到 put_url,必須原樣帶上回應裡的 content_type(它參與簽名,改一個字就是 403);
  3. 提交對齊時傳 audio_object_key 而不是 audio_url。

憑證是一次性的:對齊跑完(成功或失敗)伺服器會刪掉這個物件,同一個 key 再用會報錯。

新增:歌詞可以不傳了

原本外部歌曲必須給歌詞。現在不傳也能用——伺服器先做一次辨識,用辨識出來的文字當歌詞。

代價必須說清楚:文字以辨識結果為準,個別字可能不準。這類回應會明確標註 lyrics_source: "asr"、confidence: "low",並在 warnings[] 裡給 {"code":"no_reference_lyrics"}。

要做逐字高亮 / KTV,請務必提供歌詞原文。

請求參數

Headers

參數名 型別 必填 說明
Authorization string 是 Bearer YOUR_API_KEY
Content-Type string 是 application/json

Body 參數

參數名 型別 必填 預設值 說明
song_id string 二選一 - 平台歌曲 ID(平台歌曲用法)
lyrics string 否 - 歌詞原文,\n 分行。現在可以不傳,見上文「歌詞可以不傳了」
audio_url string 外部歌曲二選一 - 音訊位址,必須公網可下載
audio_object_key string 外部歌曲二選一 - 直傳物件的 key(先呼叫 /lyrics-align/upload-ticket)
vocal_separate boolean 否 false 是否先做人聲分離(僅平台歌曲)
language string 否 自動判斷 Chinese / English 等;不傳按歌詞內容猜
granularity string 否 both both / line(不回傳逐字)/ word
sections string 否 keep keep 保留 [Chorus] 等段落標記(不參與時間軸)/ drop
format string 否 json json / lrc / lrc-word(後兩者多回傳 lrc、lrc_word 文字)

限制

項 限制
音訊長度 ≤ 6 分鐘(超過回傳錯誤並全額退款)
音訊來源 必須公網可下載,不接受需要登入態的位址
歌詞格式 純文字、\n 分行;[Verse]、【主歌】 等段落標記會原樣保留,但不參與時間軸
批次 一次一首;多首請自行迴圈呼叫
結果保存 本介面不落庫,請自行保存回傳結果

請求範例

外部歌曲(歌詞 + 音訊位址)

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": "漫步在清冷的街頭\n夜風輕撫過眼眸\n歲月匆匆如水流",
    "audio_url": "https://your-bucket.example.com/song.mp3"
  }'

平台歌曲(不分離)

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"}'

平台歌曲 + 人聲分離(做卡拉OK推薦這個)

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}'

回應結果

成功回應

{
  "success": true,
  "lyrics_source": "platform",
  "vocal_separate": false,
  "coverage": 0.935,
  "exact": 196,
  "fuzzy": 4,
  "total": 214,
  "lines": [
    {
      "text": "漫步在清冷的街頭",
      "start": 21.66,
      "end": 24.06,
      "chars": [
        {"char": "漫", "start": 21.66, "end": 21.74, "word": true},
        {"char": "步", "start": 21.98, "end": 22.22, "word": true}
      ]
    }
  ]
}

欄位說明

欄位名 型別 說明
success boolean 請求是否成功
lyrics_source string platform = 歌詞取自平台歌曲;user = 歌詞由你提供;asr = 你沒給歌詞,文字來自辨識
vocal_separate boolean 本次是否走人聲分離
confidence string high / low(lyrics_source=asr 時一定是 low)
warnings[] array 降級提示;無歌詞時含 {"code":"no_reference_lyrics"}
coverage number 對齊品質:有明確時間錨點的字佔比(0–1)
exact / fuzzy / total number 精確命中字數 / 同音命中字數 / 歌詞有效字數
lines[].text string 一行歌詞,逐字元等於你的原文
lines[].start / end number 這一行的起止時間(秒)
lines[].section boolean 這行是段落標記(true 時沒有時間,不參與高亮)
lines[].chars[] array 逐字時間:char 字、start/end 秒、word 是否計入時間軸(標點為 false)
words[] array 扁平逐字清單:text / start / end / line;granularity=line 時不回傳
lrc string 逐行 LRC 文字(format=lrc 或 lrc-word 時才有)
lrc_word string 增強逐字 LRC,行內 <mm:ss.xx> 標籤(format=lrc-word 時才有)

coverage 怎麼用(三檔建議)

coverage 建議用法
≥ 0.9 可以做逐字高亮(卡拉OK)
0.8 – 0.9 逐字 + 整行混用,或只做整行高亮,逐字僅作參考
< 0.8 建議只做整行高亮(重唱、和聲重、方言、說唱容易偏低)

狀態與耗時

場景 實測耗時
平台歌曲 · 不分離 約 4.5 秒
平台歌曲 · 分離(已有人聲軌) 約 11 秒
平台歌曲 · 分離(需現場分離) 約 25 秒,最長約 1 分鐘
外部歌曲 · 歌詞 + 音訊位址 約 5–15 秒(視音訊長度)

伺服器單次執行上限 8 分鐘;建議用戶端逾時設定為 120 秒以上。

錯誤回應

{
  "success": false,
  "message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
場景 是否扣費
缺少音訊(三個都不傳) 不扣費(未開始處理)
audio_url 與 audio_object_key 同時傳 不扣費(未開始處理)
直傳物件還沒落盤 / 已被刪除 不扣費(未開始處理)
非法的 granularity / sections / format 不扣費(未開始處理)
平台歌曲不存在 / 不屬於目前帳號 不扣費(未開始處理)
參數缺失或參數不合法 不扣費(未開始處理)
音訊超過 6 分鐘上限 全額退款
音訊不可下載(非公網位址 / 需要登入) 全額退款
不傳歌詞、但伺服器辨識失敗 全額退款
勾了人聲分離但沒有可用人聲軌 全額退款(含人聲分離費用)
對齊服務異常或逾時 全額退款

原則:拿不到最終結果就全額退款。 只有真正回傳了逐字時間戳才扣費,退款自動完成、無需申請。

計費

項目 何時收 說明
歌詞時間戳校正(基準) 每次都收 按次計費(目前預設 0.1 元/次),實際扣費以目前後台價格設定為準
轉寫附加費 只有不提供歌詞時加收 伺服器要先跑一次語音辨識,那是「有歌詞」檔沒有的成本,所以單獨計價
人聲分離(可選,僅平台歌曲) 勾了 vocal_separate 時 按平台「人聲/伴奏分離」的現有價格計一次,與本介面一起結算

組合關係:

實付 = 基準價 + (不提供歌詞 ? 轉寫附加費 : 0) + (勾了分離 ? 分離價 : 0)

人聲分離費用只收一次:如果你已經做過分離、能直接拿到人聲軌,就由本介面收;如果需要現場分離,則由分離那一步收。

完整範例(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("對齊品質 coverage =", res["coverage"])
for line in res["lines"]:
    print(f'{line["start"]:7.2f}  {line["text"]}')
    # 逐字卡拉OK:line["chars"] 裡每個字都有自己的 start / end

常見問題

Q:回傳的是逐字還是逐行? A:兩者都有。lines[].start 是逐行,lines[].chars[].start / end 是逐字,播放器按需取用。

Q:為什麼回傳的文字和我傳的一模一樣? A:設計如此。我們不做辨識改寫,只做時間對齊,所以歌詞永遠不會被「改錯字」。

Q:coverage 很高,但聽起來還是有點偏? A:逐字對齊誤差通常在數十毫秒量級;如果整首歌都偏一個固定值,多半是音訊開頭有一段靜音,可以裁剪後再試。

Q:為什麼剛剛做了人聲分離能用,過一會兒就報「人聲軌不可用」? A:分離結果是短時效的臨時位址(實測約半小時後失效)。這種情況介面會嘗試自動重新分離;如果最終仍然失敗,會全額退款。所以「先分離、過一會兒再做校正」這種用法不可靠,建議在同一個流程裡連著做。

Q:平台歌曲需要我自己先做分離嗎? A:不需要。勾 vocal_separate: true 後我們會檢查這首歌是否已有人聲軌;沒有可用人聲軌會報錯並退款,不會用原曲糊弄。

Q:可以批次嗎? A:一次請求一首。批次請迴圈呼叫;每次呼叫都會正常計費,建議本地快取結果。

Q:結果會被保存嗎? A:本介面不落庫,請自行保存回傳值(逐行 + 逐字時間戳都在回應裡)。

下一篇音樂商用授權書 API

取得 API 金鑰

註冊後即可在主控台建立 API 金鑰。每次生成 0.6 元可得 2 首歌,下載不限次數,且不需要手機號碼。

取得 API 金鑰 回到總覽