mcpField
T
text-to-speech

text-to-speech

github.com/heygen-comクリエイティブ・メディア5251.2k 回インストール15 週間前に更新
リポジトリ

text-to-speech について

HeyGen v3 APIのStarfish TTSモデルで、テキストから音声ファイルを生成するスキルです。音声の検索に加え、SSML、速度、言語、ロケールを指定できます。

主な機能

  1. 01Starfish対応音声の検索
  2. 02テキストまたはSSMLから音声を生成
  3. 03速度・言語・ロケールの指定
  4. 04単語タイムスタンプによる同期
  5. 05ページ分割された音声一覧

活用シーン

  1. 01選んだ音声でナレーションを作成
  2. 02SSMLのポーズやマークアップを使った音声生成
  3. 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_voicesGET /v3/voices?engine=starfish
音声の生成mcp__heygen__text_to_speechPOST /v3/voices/speech

デフォルトのワークフロー

  1. mcp__heygen__list_audio_voices(または GET /v3/voices?engine=starfish)で音声を一覧表示します
  2. 希望する言語、性別、特徴に合った音声を選択します
  3. テキストと voice_id を指定して mcp__heygen__text_to_speech(または POST /v3/voices/speech)を呼び出します
  4. 返された audio_url を使用して、音声をダウンロードまたは再生します

TTS 音声の一覧表示

Starfish TTS モデルに対応する音声を取得します。

注: 統合された GET /v3/voices エンドポイントで engine=starfish フィルターを使用し、TTS 対応の音声のみを返します。すべての動画音声が Starfish TTS に対応しているわけではありません。レスポンスはページ分割されます。追加のページを取得するには next_token を使用してください。

クエリパラメーター
パラメーター型説明
enginestringエンジンでフィルターします(TTS 音声には starfish を使用)
typestringpublic または private
languagestring言語でフィルターします
genderstring性別でフィルターします
limitinteger1 ページあたりの結果数、1~100
tokenstringnext_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

リクエストフィールド
フィールド型必須説明
textstringY変換するテキストコンテンツ(1~5000 文字)
voice_idstringYGET /v3/voices?engine=starfish で取得した音声 ID
input_typestring"text"(デフォルト)または完全な SSML マークアップ用の "ssml"
speednumber読み上げ速度、0.5~2.0(デフォルト:1.0)
languagestring基本言語コード(例:"en"、"pt")。省略時は自動検出されます
localestring多言語音声用の 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"
}

ベストプラクティス

  1. GET /v3/voices?engine=starfish を使用して対応する音声を探します。統合された /v3/voices エンドポイントはすべての音声タイプを提供するため、TTS では engine=starfish フィルターが必須です
  2. locale を設定する前にsupport_locale を確認します。ロケールの選択に対応しているのは、多言語音声のみです
  3. 自然な音声出力にするには、速度を 0.8~1.2 に保ちます
  4. 音声を生成する前に、preview_audio_url を使用してプレビューします(一部の音声では null の場合があります)
  5. キャプションの同期やタイミング付きテキストオーバーレイには、レスポンス内の word_timestamps を使用します
  6. 一時停止を入れるには、テキスト内で SSML の break タグを使用します:word <break time="1s"/> word
  7. 単純な break タグを超える SSML マークアップの完全な制御が必要な場合は、input_type: "ssml" を使用します
  8. 音声一覧をページネーションします。v3 エンドポイントはページネーションされた結果を返すため、すべての音声を取得するには has_more と next_token を使用します

コメント