歌詞タイムスタンプ校正 API
これは音声認識ではありません。 文字は必ずお客様が渡した歌詞原文をそのまま採用し、私たちは各文字を正しい時刻に置くだけです——だから「認識ミスで歌詞がずれる」ことは起きません。
インターフェースの説明
既存の歌詞と音声を揃え、行単位+文字単位のタイムスタンプを出力します。カラオケの逐字ハイライト、スクロール歌詞、字幕生成に使えます。
エンドポイント: POST /api/music/lyrics-align
認証: 認証を参照。リクエストヘッダーは Authorization: Bearer YOUR_API_KEY
課金: 1 回ごとの課金(現在は既定で 1 回 0.1 元)。プラットフォーム楽曲で人声分離を選んだ場合は、プラットフォームの「人声/伴奏分離」価格でもう 1 回課金されます。実際の請求額は現在の管理画面の価格設定に従います。
平均所要時間: 5〜15 秒(音声の長さ、およびその場で人声分離が必要かどうかによります)
校正が必要な理由:生成側のタイムスタンプは常に正確とは限らない
タイムライン歌詞 API は生成側の逐語タイムスタンプをそのまま返しますが、不正確さがあります:
- 繰り返し、ハモリが多い曲、ラップ、ロングトーンでは全体がずれたり一部の文字がずれたりしやすい;
- 一部の曲は冒頭が欠ける(例:純粋な前奏で、最初の断片が十数秒から始まる);
- 明確な時間アンカーが取りにくい歌詞行がある。
歌詞タイムスタンプ校正は、お客様が提供した歌詞を土台に時間合わせをやり直すもので、時間だけを校正し、文字は変えません。「合うかどうか」が重要な用途(KTV の逐字ハイライト、逐字字幕、歌ってみたの採点)に向いています。
推奨手順(3 ステップ、最も効果的)
- まず純粋な人声を抽出(人声/伴奏分離)し、人声トラックだけを揃えます——伴奏とハモリが邪魔をしなくなります。 実測根拠:同じ曲の「フルミックス vs 人声トラック」を行ごとに比較すると、28 行のうち 5 行が 0.25 秒以上ずれ(最大 2.64 秒)ていました。 独立した 2 つのエンジンは、人声トラックでは平均差 0.239 秒、フルミックスでは 0.508 秒——一致度がほぼ半分です。 そのため逐字ハイライト(KTV/字幕)では有効化を推奨します。(改善幅は新しいエンジンで再測定中です。)
- 完全な歌詞を渡す:曲全体、行単位、音声と一対一。文や段落が抜けると後続の行が全体的にずれます。歌詞に
[00:23.82]のようなタイムスタンプを入れないでください(入っていても自動で無視されます)。 - プラットフォーム楽曲なら
vocal_separate: trueを付けるだけで、「分離+整列」を一度に済ませられます。
3 つの使い方
| 使い方 | 渡すもの | 歌詞の出所 | 人声分離 |
|---|---|---|---|
| 外部曲 · 公開 URL | audio_url + 歌詞 |
お客様が提供 | ❌ 非対応 |
| 外部曲 · ローカルファイル直送(2026-10 追加) | audio_object_key + 歌詞 |
お客様が提供 | ❌ 非対応 |
| プラットフォーム楽曲(当サイトで生成した曲) | song_id |
楽曲レコードから取得 | ✅ 任意 |
パラメータの関係(最も間違えやすいので必ず確認してください)
song_idを渡す → プラットフォーム楽曲の経路:lyrics/audio_url/audio_object_keyは渡さないでください;audio_urlまたはaudio_object_keyを渡す → 外部曲の経路:どちらか一方だけを渡し、song_idは渡さないでください;vocal_separateはプラットフォーム楽曲にのみ有効で、外部曲で渡すと拒否されます(音声がこちらに無いため分離できません)。
追加:ローカルファイル直送(音声が当社サーバーを通りません)
音声が手元にあり、自分の公開ストレージに先に上げたくない場合に使います。2 ステップです:
POST /api/music/lyrics-align/upload-ticketにfile_name/file_size/content_typeを付けて呼び、put_url(長期の資格情報を含まない署名 URL)とobject_keyを受け取ります;- ファイルを
put_urlにPUTします。レスポンスのcontent_typeをそのまま付けてください(署名の対象なので 1 文字変えると 403 です); - 整列を送信するときは
audio_urlではなくaudio_object_keyを渡します。
資格情報は使い捨てです:整列が終わると(成功・失敗を問わず)サーバーがこのオブジェクトを削除し、同じ 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(後者 2 つは lrc、lrc_word テキストも返します) |
制限
| 項目 | 制限 |
|---|---|
| 音声の長さ | 6 分以内(超えるとエラーを返し、全額返金) |
| 音声の出所 | 公衆ダウンロード可能であること。ログイン状態が必要なアドレスは不可 |
| 歌詞の形式 | プレーンテキスト、\n で行区切り。[Verse] や 【主歌】 などの段落マーカーはそのまま保持されますが時間軸には参加しません |
| バッチ | 1 回に 1 曲。複数曲は自前でループしてください |
| 結果の保存 | 本エンドポイントは永続化しません。返却結果をご自身で保存してください |
リクエスト例
外部曲(歌詞+音声アドレス)
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"}'
プラットフォーム楽曲+人声分離(カラオケにはこれを推奨)
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 | 1 行の歌詞。1 文字ずつお客様の原文と一致 |
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 の使い方(3 段階の目安)
| coverage | 推奨する使い方 |
|---|---|
| 0.9 以上 | 逐字ハイライト(カラオケ)に使えます |
| 0.8〜0.9 | 逐字と行単位の併用、または行単位のみでハイライトし、逐字は参考程度に |
| 0.8 未満 | 行単位のハイライトのみを推奨(繰り返し、ハモリが多い曲、方言、ラップは低くなりがち) |
状態と所要時間
| シナリオ | 実測時間 |
|---|---|
| プラットフォーム楽曲 · 分離なし | 約 4.5 秒 |
| プラットフォーム楽曲 · 分離(人声トラックあり) | 約 11 秒 |
| プラットフォーム楽曲 · 分離(その場で分離が必要) | 約 25 秒、最長約 1 分 |
| 外部曲 · 歌詞+音声アドレス | 約 5〜15 秒(音声の長さによる) |
サーバー側の 1 回の実行上限は 8 分です。クライアントのタイムアウトは 120 秒以上を推奨します。
エラー応答
{
"success": false,
"message": "音频超过 6 分钟上限(实际 7.2 分钟)"
}
| シナリオ | 課金の有無 |
|---|---|
| 音声が無い(3 つとも未指定) | 課金なし(処理を開始していません) |
audio_url と audio_object_key を同時に指定 |
課金なし(処理を開始していません) |
| 直送オブジェクトがまだ保存されていない/削除済み | 課金なし(処理を開始していません) |
不正な granularity / sections / format |
課金なし(処理を開始していません) |
| プラットフォーム楽曲が存在しない/現在のアカウントのものではない | 課金なし(処理を開始していません) |
| パラメータの欠落または不正 | 課金なし(処理を開始していません) |
| 音声が 6 分の上限を超過 | 全額返金 |
| 音声がダウンロード不可(非公開アドレス/ログイン必須) | 全額返金 |
| 歌詞を渡さず、サーバー側の認識も失敗 | 全額返金 |
| 人声分離を選んだが使える人声トラックが無い | 全額返金(人声分離費用を含む) |
| 整列サービス異常またはタイムアウト | 全額返金 |
原則:最終結果が得られなければ全額返金。 逐字タイムスタンプが実際に返ったときだけ課金され、返金は自動で完了します(申請不要)。
課金
| 項目 | いつ課金されるか | 説明 |
|---|---|---|
| 歌詞タイムスタンプ校正(基準) | 毎回 | 1 回ごとの課金(現在は既定で 1 回 0.1 元)。実際の請求額は現在の管理画面の価格設定に従います |
| 転写追加料金 | 歌詞を提供しないときのみ加算 | サーバーが先に音声認識を 1 回走らせる必要があり、「歌詞あり」の区分には無いコストなので別建てです |
| 人声分離(任意、プラットフォーム楽曲のみ) | vocal_separate を付けたとき |
プラットフォームの既存「人声/伴奏分離」価格で 1 回だけ課金し、本エンドポイントと合わせて精算します |
組み合わせ:
実払い = 基準価格 + (歌詞を提供しない ? 転写追加料金 : 0) + (分離を指定 ? 分離価格 : 0)
人声分離の費用は 1 回だけ:すでに分離済みで人声トラックを直接取得できる場合は本エンドポイントが、その場で分離が必要な場合は分離のステップが課金します。
完全な例(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"]}')
# 逐字カラオケ:line["chars"] の各文字にそれぞれ start / end があります
よくある質問
Q:返るのは逐字ですか行単位ですか?
A:両方です。lines[].start は行単位、lines[].chars[].start / end は逐字で、プレイヤーが必要な方を使います。
Q:なぜ返る文字が渡したものとまったく同じなのですか? A:設計どおりです。私たちは認識による書き換えを行わず、時間合わせだけを行うので、歌詞が「誤字に直される」ことはありません。
Q:coverage は高いのに、まだ少しずれて聞こえます。
A:逐字整列の誤差は通常数十ミリ秒程度です。曲全体が一定量ずれているなら、音声の冒頭に無音がある可能性が高いので、切り詰めてから再試行してください。
Q:さっきは人声分離で使えたのに、しばらくすると「人声トラックが使えません」と言われます。 A:分離結果は短命な一時アドレスです(実測で約 30 分後に失効)。その場合エンドポイントは自動で再分離を試みます。それでも失敗すると全額返金します。つまり「先に分離して、あとで校正」は当てにできません。同じフローの中で続けて行ってください。
Q:プラットフォーム楽曲は自分で先に分離する必要がありますか?
A:不要です。vocal_separate: true を付けると、その曲に人声トラックがあるかを確認します。使える人声トラックが無ければエラーにして返金します(原曲でごまかすことはしません)。
Q:バッチ処理はできますか? A:1 リクエスト 1 曲です。バッチはループしてください。毎回きちんと課金されるので、結果をローカルにキャッシュすることをおすすめします。
Q:結果は保存されますか? A:本エンドポイントは永続化しません。返却値をご自身で保存してください(行単位+逐字のタイムスタンプはレスポンスに含まれています)。