text-to-speech について
HeyGen v3 APIのStarfish TTSモデルで、テキストから音声ファイルを生成するスキルです。音声の検索に加え、SSML、速度、言語、ロケールを指定できます。
主な機能
- 01Starfish対応音声の検索
- 02テキストまたはSSMLから音声を生成
- 03速度・言語・ロケールの指定
- 04単語タイムスタンプによる同期
- 05ページ分割された音声一覧
活用シーン
- 01選んだ音声でナレーションを作成
- 02SSMLのポーズやマークアップを使った音声生成
- 03単語タイムスタンプを使った字幕同期
MCP 対応
HeyGen MCPツールが利用可能な場合、TTS音声の一覧取得と音声生成に使うことを推奨しています。利用できない場合はHeyGen v3 HTTP APIを使います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ heygen-com/ skills --skill text-to-speechインストール後、Claude Code で/text-to-speechを入力して読み込まれたか確認します。
詳細
テキスト読み上げ(HeyGen Starfish)
HeyGen 独自の Starfish TTS モデルを v3 API 経由で使用し、テキストから音声ファイルを生成します。このスキルは単独での音声生成を対象としており、動画作成とは別です。
認証
すべてのリクエストで X-Api-Key ヘッダーが必要です。HEYGEN_API_KEY 環境変数を設定してください。
curl -X GET "https://api.heygen.com/v3/voices?engine=starfish" \
-H "X-Api-Key: $HEYGEN_API_KEY"
ツールの選択
HeyGen MCP ツール(mcp__heygen__*)が利用可能な場合は、直接 HTTP API を呼び出すよりも優先して使用してください。
| タスク | MCP ツール | フォールバック(直接 API) |
|---|---|---|
| TTS 音声の一覧表示 | mcp__heygen__list_audio_voices | GET /v3/voices?engine=starfish |
| 音声の生成 | mcp__heygen__text_to_speech | POST /v3/voices/speech |
デフォルトのワークフロー
mcp__heygen__list_audio_voices(またはGET /v3/voices?engine=starfish)で音声を一覧表示します- 希望する言語、性別、特徴に合った音声を選択します
- テキストと voice_id を指定して
mcp__heygen__text_to_speech(またはPOST /v3/voices/speech)を呼び出します - 返された
audio_urlを使用して、音声をダウンロードまたは再生します
TTS 音声の一覧表示
Starfish TTS モデルに対応する音声を取得します。
注: 統合された
GET /v3/voicesエンドポイントでengine=starfishフィルターを使用し、TTS 対応の音声のみを返します。すべての動画音声が Starfish TTS に対応しているわけではありません。レスポンスはページ分割されます。追加のページを取得するにはnext_tokenを使用してください。
クエリパラメーター
| パラメーター | 型 | 説明 |
|---|---|---|
engine | string | エンジンでフィルターします(TTS 音声には starfish を使用) |
type | string | public または private |
language | string | 言語でフィルターします |
gender | string | 性別でフィルターします |
limit | integer | 1 ページあたりの結果数、1~100 |
token | string | next_token から取得したページネーションカーソル |
curl
curl -X GET "https://api.heygen.com/v3/voices?engine=starfish" \
-H "X-Api-Key: $HEYGEN_API_KEY"
TypeScript
interface AudioVoiceItem {
voice_id: string;
name: string;
language: string;
gender: "female" | "male" | "unknown";
preview_audio_url: string | null;
support_pause: boolean;
support_locale: boolean;
type: string;
}
interface TTSVoicesResponse {
error: null | string;
data: AudioVoiceItem[];
has_more: boolean;
next_token: string | null;
}
async function listTTSVoices(): Promise<AudioVoiceItem[]> {
const allVoices: AudioVoiceItem[] = [];
let token: string | null = null;
do {
const url = new URL("https://api.heygen.com/v3/voices");
url.searchParams.set("engine", "starfish");
if (token) url.searchParams.set("token", token);
const response = await fetch(url.toString(), {
headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! },
});
const json: TTSVoicesResponse = await response.json();
if (json.error) {
throw new Error(json.error);
}
allVoices.push(...json.data);
token = json.next_token;
} while (token);
return allVoices;
}
Python
import requests
import os
def list_tts_voices() -> list:
all_voices = []
token = None
while True:
params = {"engine": "starfish"}
if token:
params["token"] = token
response = requests.get(
"https://api.heygen.com/v3/voices",
headers={"X-Api-Key": os.environ["HEYGEN_API_KEY"]},
params=params,
)
data = response.json()
if data.get("error"):
raise Exception(data["error"])
all_voices.extend(data["data"])
if not data.get("has_more"):
break
token = data.get("next_token")
return all_voices
レスポンス形式
{
"error": null,
"data": [
{
"voice_id": "f38a635bee7a4d1f9b0a654a31d050d2",
"name": "Chill Brian",
"language": "English",
"gender": "male",
"preview_audio_url": "https://resource.heygen.ai/text_to_speech/WpSDQvmLGXEqXZVZQiVeg6.mp3",
"support_pause": true,
"support_locale": false,
"type": "public"
}
],
"has_more": false,
"next_token": null
}
音声の生成
指定した音声を使用して、テキストを音声に変換します。
エンドポイント
POST https://api.heygen.com/v3/voices/speech
リクエストフィールド
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
text | string | Y | 変換するテキストコンテンツ(1~5000 文字) |
voice_id | string | Y | GET /v3/voices?engine=starfish で取得した音声 ID |
input_type | string | "text"(デフォルト)または完全な SSML マークアップ用の "ssml" | |
speed | number | 読み上げ速度、0.5~2.0(デフォルト:1.0) | |
language | string | 基本言語コード(例:"en"、"pt")。省略時は自動検出されます | |
locale | string | 多言語音声用の BCP-47 ロケール(例:"en-US"、"pt-BR") |
curl
curl -X POST "https://api.heygen.com/v3/voices/speech" \
-H "X-Api-Key: $HEYGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello! Welcome to our product demo.",
"voice_id": "YOUR_VOICE_ID",
"speed": 1.0
}'
TypeScript
interface TTSRequest {
text: string;
voice_id: string;
input_type?: "text" | "ssml";
speed?: number;
language?: string;
locale?: string;
}
interface WordTimestamp {
word: string;
start: number;
end: number;
}
interface TTSResponse {
error: null | string;
data: {
audio_url: string;
duration: number;
request_id?: string;
word_timestamps?: WordTimestamp[];
};
}
async function textToSpeech(request: TTSRequest): Promise<TTSResponse["data"]> {
const response = await fetch(
"https://api.heygen.com/v3/voices/speech",
{
method: "POST",
headers: {
"X-Api-Key": process.env.HEYGEN_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
}
);
const json: TTSResponse = await response.json();
if (json.error) {
throw new Error(json.error);
}
return json.data;
}
Python
import requests
import os
def text_to_speech(
text: str,
voice_id: str,
input_type: str = "text",
speed: float = 1.0,
language: str | None = None,
locale: str | None = None,
) -> dict:
payload = {
"text": text,
"voice_id": voice_id,
"speed": speed,
}
if input_type != "text":
payload["input_type"] = input_type
if language:
payload["language"] = language
if locale:
payload["locale"] = locale
response = requests.post(
"https://api.heygen.com/v3/voices/speech",
headers={
"X-Api-Key": os.environ["HEYGEN_API_KEY"],
"Content-Type": "application/json",
},
json=payload,
)
data = response.json()
if data.get("error"):
raise Exception(data["error"])
return data["data"]
レスポンス形式
{
"error": null,
"data": {
"audio_url": "https://resource2.heygen.ai/text_to_speech/.../id=365d46bb.wav",
"duration": 5.526,
"request_id": "p38QJ52hfgNlsYKZZmd9",
"word_timestamps": [
{ "word": "<start>", "start": 0.0, "end": 0.0 },
{ "word": "Hey", "start": 0.079, "end": 0.219 },
{ "word": "there,", "start": 0.239, "end": 0.459 },
{ "word": "<end>", "start": 5.526, "end": 5.526 }
]
}
}
使用例
基本的な TTS
const result = await textToSpeech({
text: "Welcome to our quarterly earnings call.",
voice_id: "YOUR_VOICE_ID",
});
console.log(`Audio URL: ${result.audio_url}`);
console.log(`Duration: ${result.duration}s`);
速度を調整する場合
const result = await textToSpeech({
text: "We're thrilled to announce our newest feature!",
voice_id: "YOUR_VOICE_ID",
speed: 1.1,
});
多言語音声で言語とロケールを指定する場合
const result = await textToSpeech({
text: "Bem-vindo ao nosso produto.",
voice_id: "MULTILINGUAL_VOICE_ID",
language: "pt",
locale: "pt-BR",
});
SSML 入力を使用する場合
const result = await textToSpeech({
text: '<speak>Hello <break time="1s"/> and welcome!</speak>',
voice_id: "YOUR_VOICE_ID",
input_type: "ssml",
});
音声を探して生成する場合
async function generateSpeech(text: string, language: string): Promise<string> {
const voices = await listTTSVoices();
const voice = voices.find(
(v) => v.language.toLowerCase().includes(language.toLowerCase())
);
if (!voice) {
throw new Error(`No TTS voice found for language: ${language}`);
}
const result = await textToSpeech({
text,
voice_id: voice.voice_id,
});
return result.audio_url;
}
const audioUrl = await generateSpeech("Hello and welcome!", "english");
Break タグによる一時停止
一時停止を挿入するには、テキスト内で SSML 形式の break タグを使用します。
word <break time="1s"/> word
ルール:
- 秒数には
sの接尾辞を付けます:<break time="1.5s"/> - タグの前後にはスペースが必要です
- 自己終了タグ形式を使用します
v3 では input_type: "ssml" を使用して完全な SSML にも対応できます。これにより、break タグ以外のより豊富なマークアップを使用できます。
{
"text": "<speak>Welcome! <break time=\"1s\"/> Let's get started.</speak>",
"voice_id": "YOUR_VOICE_ID",
"input_type": "ssml"
}
ベストプラクティス
GET /v3/voices?engine=starfishを使用して対応する音声を探します。統合された/v3/voicesエンドポイントはすべての音声タイプを提供するため、TTS ではengine=starfishフィルターが必須ですlocaleを設定する前にsupport_localeを確認します。ロケールの選択に対応しているのは、多言語音声のみです- 自然な音声出力にするには、速度を 0.8~1.2 に保ちます
- 音声を生成する前に、
preview_audio_urlを使用してプレビューします(一部の音声では null の場合があります) - キャプションの同期やタイミング付きテキストオーバーレイには、レスポンス内の
word_timestampsを使用します - 一時停止を入れるには、テキスト内で SSML の break タグを使用します:
word <break time="1s"/> word - 単純な break タグを超える SSML マークアップの完全な制御が必要な場合は、
input_type: "ssml"を使用します - 音声一覧をページネーションします。v3 エンドポイントはページネーションされた結果を返すため、すべての音声を取得するには
has_moreとnext_tokenを使用します