mcpField
O
openrouter-tts

openrouter-tts

github.com/openrouterteam创意与媒体309258 次安装1 天前更新
代码仓库

关于 openrouter-tts

openrouter-tts 是通过 OpenRouter 音频语音接口合成语音的技能指南,涵盖请求参数、音色查询、输出格式、SDK 用法及长文本处理。

主要功能

  1. 01通过 OpenRouter 合成语音
  2. 02查询模型及支持的音色
  3. 03MP3 和 PCM 输出说明
  4. 04提供商专属选项
  5. 05长文本分块流程

适用场景

  1. 01将文本生成语音文件
  2. 02查找模型可用音色
  3. 03为流式管线准备音频
  4. 04分块合成长篇文章或脚本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/openrouterteam/skills --skill openrouter-tts

安装后在 Claude Code 中输入/openrouter-tts确认已加载。

附带文件README.md

详细介绍

OpenRouter 文本转语音

使用 curl 通过 POST /api/v1/audio/speech 合成语音。该端点兼容 OpenAI,因此只需将 OpenAI SDK 指向 https://openrouter.ai/api/v1 即可使用。需要设置 OPENROUTER_API_KEY(前往 https://openrouter.ai/keys 获取)。如果未设置,请停止并询问。

一次调用,返回原始字节

响应正文是音频字节——请使用与 response_format 匹配的扩展名将其写入文件。它不是 JSON;错误响应才是 JSON,因此只有在状态码非 200 时才尝试解析 JSON。

有两个响应标头值得保留:

  • Content-Type — mp3 对应 audio/mpeg;pcm 对应的值包含采样率和声道数,例如 audio/pcm;rate=24000;channels=1。如果需要将原始字节封装到 WAV 容器中,请解析这些参数。
  • X-Generation-Id — 生成 ID(格式为 gen-tts-<timestamp>-<suffix>),可用于跟踪、调试和查询费用。

即用型工作流

#!/usr/bin/env bash
set -euo pipefail

MODEL="openai/gpt-4o-mini-tts-2025-12-15"
VOICE="alloy"
FORMAT="mp3"                          # mp3 or pcm
INPUT="Hello! This is a text-to-speech test."
OUTPUT="speech-$(date +%Y%m%d-%H%M%S).${FORMAT}"
HEADERS=$(mktemp)

payload=$(jq -n --arg model "$MODEL" --arg input "$INPUT" \
               --arg voice "$VOICE" --arg fmt "$FORMAT" \
  '{model: $model, input: $input, voice: $voice, response_format: $fmt}')

http_code=$(curl -sS -X POST https://openrouter.ai/api/v1/audio/speech \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -D "$HEADERS" \
  --output "$OUTPUT" \
  -w '%{http_code}' \
  -d "$payload")

if [[ "$http_code" != "200" ]]; then
  echo "TTS failed (HTTP $http_code):" >&2
  cat "$OUTPUT" >&2                   # error body is JSON, not audio
  rm -f "$OUTPUT" "$HEADERS"
  exit 1
fi

gen_id=$(grep -i '^x-generation-id:' "$HEADERS" | awk '{print $2}' | tr -d '\r')
rm -f "$HEADERS"
echo "Saved $(realpath "$OUTPUT") (generation_id=${gen_id:-unknown})"

发现 TTS 模型和音色

按输出模态筛选模型端点,列出语音模型。每个模型都带有一个 supported_voices 数组,其中包含该提供商支持的确切音色 ID。

# Models + voices in one shot
curl -sS "https://openrouter.ai/api/v1/models?output_modalities=speech" \
  | jq '.data[] | {id, name, supported_voices, pricing}'

# Just the voices for a specific model
curl -sS "https://openrouter.ai/api/v1/models?output_modalities=speech" \
  | jq -r '.data[] | select(.id=="openai/gpt-4o-mini-tts-2025-12-15") | .supported_voices[]'

音色使用提供商命名空间:OpenAI 使用简短名称(alloy、nova),Voxtral 编码语言、角色和情绪(en_paul_happy),Kokoro 使用语言/性别前缀(af_bella = 美式英语女声 Bella)。

参数

字段必填说明
model是TTS 模型标识(例如 openai/gpt-4o-mini-tts-2025-12-15、mistralai/voxtral-mini-tts-2603)。
input是要合成的文本。
voice是音色标识。请在模型端点的 supported_voices 中查找对应模型支持的确切音色(参见上方的发现部分)。音色使用提供商命名空间——例如,alloy 是 OpenAI 音色,无法用于 Voxtral 或 Kokoro。
response_format否mp3 或 pcm。默认值为 pcm。请明确设置此项——通常用户并不希望使用默认值保存文件。
speed否播放速度倍数(例如 1.25)。OpenAI TTS 会采用此参数。其他提供商可能接受但忽略该参数,也可能拒绝未知字段——如果这点很重要,请检查提供商的行为。
provider否提供商透传——见下文。
选择格式
  • mp3(audio/mpeg)——压缩格式,可在任何音频应用中直接播放。适合用户要收听或分享的文件,是默认首选。
  • pcm(audio/pcm;rate=<rate>;channels=<n>)——未压缩的原始采样数据。响应中的 Content-Type 包含采样率和声道数(例如 OpenAI TTS 使用 rate=24000;channels=1),将字节封装到 WAV 容器中时需要这些信息。此格式延迟较低,适合实时流式处理管线,但无法独立直接播放。仅在用户明确要求原始音频或要将其传入流式系统时选择此格式。

文件扩展名应与格式匹配——将 pcm 字节保存为 .mp3 会生成任何播放器都无法打开的文件,这是最常见的“音频为空/已损坏”问题原因。

提供商专用选项

提供商透传参数放在 provider.options.<slug> 下,且只有在该提供商处理请求时才会转发。最实用的选项是 OpenAI 的 instructions,它可以在不重新训练的情况下调整语气、口音、语速或情绪:

{
  "model": "openai/gpt-4o-mini-tts-2025-12-15",
  "input": "Welcome to the show.",
  "voice": "alloy",
  "response_format": "mp3",
  "provider": {
    "options": {
      "openai": {
        "instructions": "Speak in a warm, friendly tone with a slow pace."
      }
    }
  }
}

对于其他提供商,请查阅各提供商的上游文档,了解可用的透传键——命名约定各不相同(OpenAI/Google 使用 camelCase,其他大多数提供商使用 snake_case)。

OpenAI SDK 兼容性

由于该端点与 OpenAI 的 /audio/speech 相同,只需替换基础 URL,两个 OpenAI SDK 都能正常工作。如果用户已经在 Python/TypeScript 项目中,并且不想调用命令行,建议优先使用这种方式。

# Python — streaming write to file
import os
from openai import OpenAI

client = OpenAI(base_url="https://openrouter.ai/api/v1",
                api_key=os.environ["OPENROUTER_API_KEY"])

with client.audio.speech.with_streaming_response.create(
    model="openai/gpt-4o-mini-tts-2025-12-15",
    input="The quick brown fox jumps over the lazy dog.",
    voice="nova",
    response_format="mp3",
) as response:
    response.stream_to_file("output.mp3")
// TypeScript — collect bytes, write once
import OpenAI from "openai";
import fs from "fs";

const client = new OpenAI({
  baseURL: "https://openrouter.ai/api/v1",
  apiKey: process.env.OPENROUTER_API_KEY!,
});

const response = await client.audio.speech.create({
  model: "openai/gpt-4o-mini-tts-2025-12-15",
  input: "The quick brown fox jumps over the lazy dog.",
  voice: "nova",
  response_format: "mp3",
});

await fs.promises.writeFile(
  "output.mp3",
  Buffer.from(await response.arrayBuffer()),
);

长文本输入

TTS 模型对每次请求的字符数有限制(通常为几千个字符),并且按输入字符数计费,因此拆分文本不会产生额外费用。对于较长的内容(章节、文章、脚本):

  1. 在句子或段落边界处拆分文本,切勿在单词中间拆分。
  2. 使用相同的 model + voice 合成每个文本块,以保持韵律一致。
  3. 拼接生成的音频文件。对于 mp3,简单情况下可使用 ffmpeg -i "concat:part1.mp3|part2.mp3" -c copy out.mp3;对于比特率不同或需要无缝衔接的情况,可通过 ffmpeg -f concat -safe 0 -i list.txt output.mp3 重新编码。

如果将文本块生成后立即流式传输给用户,拆分也能缩短首段音频的等待时间。

故障排除

音频文件“为空”或无法播放 — 几乎总是格式与扩展名不匹配。检查响应标头中的 Content-Type:将 audio/pcm 保存为 .mp3 无法播放。请使用 response_format: "mp3" 重新请求,或使用匹配的扩展名保存。

400 错误,提示 "Model X does not exist" — 模型标识写错了。请使用模型端点返回的完整日期标识(openai/gpt-4o-mini-tts-2025-12-15,而不是 gpt-4o-mini-tts)。

400 错误,并包含 ZodError — 缺少必填字段或字段类型错误。请求正文格式如下:{"success":false,"error":{"name":"ZodError","message":"[...]"}};嵌套的 message JSON 字符串会指出错误路径(例如 "path":["voice"])。

speed 不起作用 — 该提供商可能不支持此参数。OpenAI TTS 支持此参数;对于其他提供商,请先查阅上游文档再依赖此参数。

参考资料

评论

支持 Markdown