mcpField
T
text-to-speech

text-to-speech

github.com/heygen-com创意与媒体5261.2k 次安装15 周前更新
代码仓库

关于 text-to-speech

此技能通过 HeyGen v3 API 和 Starfish TTS 模型,将文本生成独立语音音频。支持查找音色,并设置 SSML、语速、语言和地区。

主要功能

  1. 01查找兼容 Starfish 的音色
  2. 02从文本或 SSML 生成音频
  3. 03设置语速、语言和地区
  4. 04使用词级时间戳进行同步
  5. 05分页查找音色

适用场景

  1. 01为选定音色生成旁白音频
  2. 02使用 SSML 停顿或标记生成语音
  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)

通过 v3 API 使用 HeyGen 自研的 Starfish TTS 模型,将文本生成为语音音频文件。此技能用于独立的音频生成,与视频创作分开。

身份验证

所有请求都需要 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按性别筛选
limitinteger每页结果数,1-100
tokenstring来自 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

请求字段
字段类型必填说明
textstringY要转换的文本内容(1-5000 个字符)
voice_idstringY来自 GET /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. 需要完全控制 SSML 标记(而不只是简单的 break 标签)时,使用 input_type: "ssml"
  8. 对声音列表进行分页——v3 端点会分页返回结果;使用 has_more 和 next_token 获取所有声音

评论

支持 Markdown