关于 openrouter-tts
openrouter-tts 是通过 OpenRouter 音频语音接口合成语音的技能指南,涵盖请求参数、音色查询、输出格式、SDK 用法及长文本处理。
主要功能
- 01通过 OpenRouter 合成语音
- 02查询模型及支持的音色
- 03MP3 和 PCM 输出说明
- 04提供商专属选项
- 05长文本分块流程
适用场景
- 01将文本生成语音文件
- 02查找模型可用音色
- 03为流式管线准备音频
- 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 模型对每次请求的字符数有限制(通常为几千个字符),并且按输入字符数计费,因此拆分文本不会产生额外费用。对于较长的内容(章节、文章、脚本):
- 在句子或段落边界处拆分文本,切勿在单词中间拆分。
- 使用相同的
model+voice合成每个文本块,以保持韵律一致。 - 拼接生成的音频文件。对于 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 支持此参数;对于其他提供商,请先查阅上游文档再依赖此参数。