【SSML対応】読み方や間を指定できる音声合成ツール
この音声合成エンドポイントは、パイプラインがすでに生成しているSSMLタグ付きテキストと、プレーンテキストの両方を受け付けます。マークアップの中から読み上げる語句を取り出し、自然な音声へ合成するため、既存のSSMLワークフローはタグをプレーンテキストに戻さずにそのまま送信できます。最初に境界をはっきりさせておきます。このエンジンが再現するのは語句であって、SSMLが記述できる細かな音響制御ではありません。
オンラインで実行
アカウントでログインし、当社のサーバー上で実行します。無料ツールはブラウザ内で動作しますが、これは上記の料金がKIT残高から差し引かれます。
SSMLとは何か、なぜ存在するのか
Speech Synthesis Markup LanguageはW3Cの標準で、何を言うかだけでなく、音声エンジンにどう言わせるかを書き手が記述できるように作られました。どこで区切るか、どの音節を強めるか、略語をどう読むか、数字の並びが日付か電話番号か単なる数量か、といった指定です。プレーンテキストは本質的にあいまいで――「2/3」は日付にも分数にも得点にもなり、抽象的にはマークアップだけがそれを確定できます――だからこそ、合成音声を制御する業界の慣行として長く使われてきました。このエンドポイントが入力として受け付けるのはこの形式であり、各タグをどう扱うかは次の節で率直に説明します。
リクエストとレスポンスの流れ
SSMLタグ付きテキスト(またはプレーンテキスト)をリクエスト本文で送信します。サービスはマークアップから読み上げる語句を取り出して合成し、タグ自体は合成の前にその中のテキストへと簡略化されます。タスクは非同期でキューに入り、ただちにtask_idを返します。生成された音声はその後、署名付きのwebhook、または24時間有効な署名付きリンクで届きます。合成されるのは語句であるため、SSMLを送っても同等のプレーンテキストを送っても同じ自然なナレーションになります。マークアップは互換性のために受け付けており、各タグが音を変えるからではありません。
このエンジンが再現するものとしないもの
これは、このページが誇張しないための率直な境界です。現在の音声エンジンはテキストの内容を読み、自然で程よい間合いの音声を作ります。SSMLの細かな制御を音響として適用することはしません。強調、音素による発音、抑揚、正確な休止の長さは入力として受け付けたうえで取り除かれ、再現されません。つまり2秒の休止タグが2秒間ラインを止めることはなく、強調タグがその語をモデル本来の読み以上に強めることもありません。これらの制御が正確に再現されることに依存する用途であれば、その機能はこのエンジンではまだ利用できません。このエンドポイントは、SSMLパイプラインが別途プレーンテキスト用の分岐を用意せずに、今日そのまま音声を生成できるように存在します。
自動生成コンテンツへの組み込み
SSMLは構造化されたテキストにすぎないため、プログラムで生成するのは容易です。コンテンツのパイプラインは、数字をタグで囲み、セクションの間に休止を挟み、名前に発音のヒントを付ける、といった処理を人手を介さずに行えます。この層の利用者にとっての価値は、すでに出力しているSSMLをそのまま受け付ける点にあります。送信前にマークアップをプレーンテキストへ落とす二本目のコード経路を作って保守する必要がありません。料金はこの軽量で的を絞ったタスクの性質を反映し、1リクエストあたりの小さな基本料金に、送信テキスト1,000文字あたりの料金を加えたものです。自動再試行のあとも、失敗したタスクが課金されることはありません。
アクセスと結果の扱い
このエンドポイントは、APIの他のすべてと同じく前払い残高を必要とします。残高のないリクエストは、部分的または劣化した結果ではなくHTTP 402を返します。送信されたテキストと生成された音声は保持期間の終了後に削除され、モデルの学習に使われることは決してありません。受け渡しはお客様のwebhookまたは一時的な署名付きリンクに限られ、その期間を超えて保存されるものはありません。
活用例
既存のSSMLパイプラインの差し替え先
すでにSSMLを出力しているワークフローをこのエンドポイントに向けるだけで、タグをプレーンテキストに落とす処理を自分で書かずに、読み上げ音声を受け取れます。
生成されたスクリプトからのナレーション
アルゴリズムで生成したスクリプトを、コンテンツパイプラインの自動化された一工程として、自然な読み上げ音声に変換します。
長文を音声に
記事やメモ、ドキュメントを音声に変換し、読むより聞くことを好む相手に届けます。
多言語の音声出力
同じリクエスト形式のまま、言語フィールドの指定に従って、対応言語で読み上げ音声を生成します。
よくある質問
SSMLとは何で、この音声合成apiはそれをどう使いますか?
SSMLは音声合成を記述するためのマークアップ標準です。このエンドポイントはSSMLタグ付きテキストを受け付け、そこから読み上げる語句を取り出して自然な音声に合成します。形式を受け付けるのは互換性のためであり、どのSSML制御が実際に再現されるかは次の回答をご覧ください。
強調・音素・抑揚のタグは再現されますか?
いいえ、現在の音声エンジンでは再現されません。これらのタグは正確な休止の長さとともに入力として受け付けられ、その後その中のテキストへ簡略化されます。音声は指定された強調・発音・休止を適用するのではなく、語句を自然に読み上げます。これらの制御の正確な音響的再現はまだ利用できません。
この音声合成apiは無料ですか?
無料枠はありません。無料枠は悪用され、全体を遅くします。アクセスはForHosting KITの前払い残高で動きます。$10.00から入金でき(失効しません)、各リクエストは公表価格で課金されるため、残高のない呼び出しはHTTP 402を返します。サブスクリプションもトークンも架空のクレジットもなく、失敗したタスクは課金されません。
料金はいくらですか?
1リクエストあたり$0.002に加え、送信テキスト1,000文字あたり$0.0025です。
基本的な音声合成にSSMLは必要ですか?
いいえ。プレーンテキストから自然な音声が得られればよいだけなら、標準の音声合成エンドポイントのほうが簡単で、同じ種類のナレーションを生成します。ここではプレーンテキストもSSMLも自然な音声として出力されます。
生成された音声はどう受け取りますか?
タスクは非同期に実行され、ただちにtask_idを返します。完成した音声は署名付きのwebhook、または24時間有効な署名付きリンクで届きます。
SSMLマークアップが不正な場合はどうなりますか?
マークアップは合成の前に読み上げるテキストへ簡略化されるため、不正なタグがあってもリクエストは失敗せず、読める語句の音声はそのまま得られます。タグの誤りで拒否されることはないので、SSMLの検証をこのエンドポイントに頼らないでください。
名前や略語の発音の制御に使えますか?
音響的にはできません。音素の制御はこのエンジンでは再現されないため、音素タグで特定の発音を強制することはできません。ある名前を特定の読み方にしたい場合は、語句そのものが発音を担うように、テキスト内で音のとおりに書いてください。
開発者向け — APIアクセス
このページの機能はすべてAPIからも利用できます。自社システムに組み込みたいチーム向けのセクションです。それ以外の方は上のツールをそのままお使いください。
エンドポイント
Bearerトークンで認証し、POST1回でタスクをキューに登録します。結果はWebhookまたは署名付きリンクで受け取れます。
お使いのスタックから呼び出す
curl -X POST https://api.kit.forhosting.com/voice/tts-ssml \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"ssml":"<speak>Hola <break time=\"500ms\"/> mundo.</speak>"}'const res = await fetch("https://api.kit.forhosting.com/voice/tts-ssml", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"ssml": "<speak>Hola <break time=\"500ms\"/> mundo.</speak>"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/voice/tts-ssml",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"ssml": "<speak>Hola <break time=\"500ms\"/> mundo.</speak>"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/voice/tts-ssml", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"ssml":"<speak>Hola <break time=\\"500ms\\"/> mundo.</speak>"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"ssml":"<speak>Hola <break time=\"500ms\"/> mundo.</speak>"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/voice/tts-ssml", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)リクエスト例
{
"ssml": "<speak>Hola <break time=\"500ms\"/> mundo.</speak>"
}レスポンス例
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "voice.tts_ssml",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}非同期APIです。task_idは即時に返ります。ポーリングは1秒あたり1リクエストまでです。
料金
単価はすべて公開しています。トークン換算や独自クレジットはありません。失敗したタスクは課金されません。
制限
max_mb | 200 |
max_minutes | 180 |
エラー
| HTTP | コード | 意味 |
|---|---|---|
401 | unauthorized | APIキーが無効か、指定されていません。Authorizationヘッダーを確認してください。 |
402 | insufficient_balance | 残高が不足しています。チャージ後に再度お試しください。 |
404 | unknown_type | 指定されたタスクタイプは存在しません。タイプ名を確認してください。 |
429 | rate_limited | リクエストが多すぎます。しばらく待ってから再度お試しください。 |