跳到正文
OpenRouter Blog·· 19 小时前精选AI 评分60

ElevenLabs 上线 OpenRouter,开放 9 款 TTS 与 2 款 STT 模型

ElevenLabs is now on OpenRouter

AI 导读

ElevenLabs 正式上线 OpenRouter,提供 9 款文本转语音模型和 2 款语音转文本模型,已有 OpenRouter 应用可直接用同一 API key 调用 POST /api/v1/audio/speech 和 POST /api/v1/audio/transcriptions。

推荐理由

原文给出九款 TTS 与两款 STT 模型在 OpenRouter 上的调用方式、价格分档和限时折扣,可直接对照选型。

正文 · AI 翻译

ElevenLabs 现已登陆 OpenRouter,带来九个文本转语音模型和两个语音转文本模型。

如果你的应用已经通过 OpenRouter 与语言模型对话,现在它也能说和听了。用 Eleven v4 为长篇内容配音,并掌控语气和表达方式;用 v4 Turbo 让智能体更快地给出语音回复;或用 Scribe v2 转录对话并标注说话人。你无需单独订阅 ElevenLabs 套餐,只需用你的 OpenRouter API 密钥调用 POST /api/v1/audio/speech 和 POST /api/v1/audio/transcriptions 即可。

即日起至太平洋时间 10 月 19 日上午 8 点,所有 OpenRouter 客户均可享受 ElevenLabs 全部模型在 OpenRouter 标价基础上的五折优惠

该用哪个模型

先从三个模型入手,遇到特定任务时再选用其余模型:

  • 旁白、角色配音、产品视频:Eleven v4。音频标签让脚本本身承载表演。
  • 语音智能体和实时回复:Eleven v4 Turbo,ElevenLabs 专为实时场景打造,费率仅为 v4 的一半。
  • 转录、会议记录、字幕:Scribe v2,支持说话人标注和词级时间戳。

当长篇音频需要语速控制时,使用 Multilingual v2;需要大批量语音合成、每次请求最多 40,000 个字符时,使用 Flash v2.5。Scribe v2 Medical 针对医学术语进行了微调。

文本转语音

模型OpenRouter ID每次请求最大字符数适用场景
Eleven v4elevenlabs/eleven-v410,000ElevenLab 音质最高、最具表现力的语音。适合富有表现力的旁白和角色配音,支持 [whispering]、[laughing] 等音频标签
Eleven v4 Turboelevenlabs/eleven-v4-turbo10,000为语音智能体提供低延迟回复
Eleven v3elevenlabs/eleven-v35,000支持音频标签的富有表现力/戏剧化的旁白和角色配音
Eleven v3 Conversationalelevenlabs/eleven-v3-conversational5,000以 v3 一半的费率实现一来一回的对话。具备戏剧化表现力,专为实时对话调校。
Eleven Multilingual v2elevenlabs/eleven-multilingual-v210,000跨多种语言的稳定长篇音频,支持语速控制。
Eleven Flash v2.5elevenlabs/eleven-flash-v2.540,000快速、低成本的多语言大批量语音合成。支持 32 种语言。
Eleven Flash v2elevenlabs/eleven-flash-v230,000快速的纯英语语音合成
Eleven Turbo v2.5elevenlabs/eleven-turbo-v2.540,000ElevenLab 第一代低延迟模型,现已被 Flash 取代
Eleven Turbo v2elevenlabs/eleven-turbo-v230,000ElevenLab 第一代低延迟模型,现已被 Flash 取代

ElevenLabs 的模型定价分为两档。Eleven v4、v3 和 Multilingual v2 按完整的每字符费率计费,v4 Turbo、v3 Conversational、Flash 和 Turbo 则按半价计费。当前的每字符价格见 文本转语音合集中各模型页面。

语音转文本

模型OpenRouter ID适用场景
Scribe v2elevenlabs/scribe-v2通用转录,支持词级时间戳、说话人标注和音频事件标签,覆盖 90 多种语言
Scribe v2 Medicalelevenlabs/scribe-v2-medical处理医学术语,在临床音频上相比 Scribe v2 错误减少 35%

两个 Scribe 模型使用相同的请求格式和相同的每秒价格。基于 WebSocket 的实时 Scribe v2 不在本次发布范围内。

演练:从第一个 MP3 到语音智能体

我们将用三步构建一个小型产品导览。首先由 Eleven v4 进行旁白。然后由语音智能体回答相关问题,最后 Scribe v2 把团队的评审会议转成能显示谁说了什么的记录。如果某个请求的表现不符合预期,请查看文末的提示。

只需设置一次密钥:

export OPENROUTER_API_KEY="your-api-key"

第 1 步:用 Eleven v4 为产品导览配音

从一句旁白开始:

curl https://openrouter.ai/api/v1/audio/speech \
  --fail-with-body \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs/eleven-v4",
    "input": "[cheerfully] Welcome to the tour. [whispering] Let me show you the shortcut first.",
    "voice": "george",
    "response_format": "mp3"
  }' \
  --output intro.mp3

voice 可按名称使用 ElevenLabs 的任意 21 个预设音色(此处为 george);名称不区分大小写。注意显式的 response_format —— 两者都请参见 首次请求的提示。

方括号中的词是音频标签。Eleven v4 和 v3 会将 [whispering]、[laughing]、[sighs] 和 [curious] 等标签作为表达指令来朗读,而不是直接念出来。标签会计入你的计费字符数。

完整的导览脚本超出了单次请求的上限(v4 为 10,000 个字符,v3 为 5,000 个字符),因此请按段落边界进行拆分。仅适用于 ElevenLabs 的设置放在 provider.options.elevenlabs 下。将相邻文本作为 previous_text 和 next_text 传入,以便在衔接处保持语调一致,并固定一个 seed,让重复运行更具可复现性:

import os

import requests

API = "https://openrouter.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"}
NARRATOR = "george"


def split_paragraphs(text: str, limit: int = 9000) -> list[str]:
    chunks, current = [], ""
    for para in text.split("\n\n"):
        if current and len(current) + len(para) + 2 > limit:
            chunks.append(current)
            current = para
        else:
            current = f"{current}\n\n{para}" if current else para
    return chunks + [current] if current else chunks


chunks = split_paragraphs(open("tour-script.txt").read())

with open("tour.mp3", "wb") as out:
    for i, chunk in enumerate(chunks):
        options = {"seed": 7}
        if i > 0:
            options["previous_text"] = chunks[i - 1][-500:]
        if i + 1 < len(chunks):
            options["next_text"] = chunks[i + 1][:500]
        r = requests.post(
            f"{API}/audio/speech",
            headers=HEADERS,
            json={
                "model": "elevenlabs/eleven-v4",
                "input": chunk,
                "voice": NARRATOR,
                "response_format": "mp3",
                "provider": {"options": {"elevenlabs": options}},
            },
        )
        r.raise_for_status()
        out.write(r.content)

第 2 步:用语音代理回答问题

现在让用户大声向导览提问。语音代理串联三个模型:用 Scribe v2 处理问题,用聊天模型生成答案,用 Eleven v4 Turbo 生成回复。ElevenLabs 专为实时使用打造了 v4 Turbo,其计费价格为 v4 的一半。

import base64


def transcribe(path: str) -> str:
    with open(path, "rb") as f:
        audio_b64 = base64.b64encode(f.read()).decode()
    r = requests.post(
        f"{API}/audio/transcriptions",
        headers=HEADERS,
        json={
            "model": "elevenlabs/scribe-v2",
            "input_audio": {"data": audio_b64, "format": "wav"},
        },
    )
    r.raise_for_status()
    return r.json()["text"]


def answer(question: str) -> str:
    r = requests.post(
        f"{API}/chat/completions",
        headers=HEADERS,
        json={
            "model": "openai/gpt-5-mini",
            "messages": [
                {"role": "system", "content": "You are the product tour guide. Answer in one or two sentences."},
                {"role": "user", "content": question},
            ],
        },
    )
    r.raise_for_status()
    return r.json()["choices"][0]["message"]["content"]


def speak(text: str, out_path: str) -> None:
    r = requests.post(
        f"{API}/audio/speech",
        headers=HEADERS,
        json={
            "model": "elevenlabs/eleven-v4-turbo",
            "input": text,
            "voice": NARRATOR,
            "response_format": "mp3",
        },
    )
    r.raise_for_status()
    with open(out_path, "wb") as f:
        f.write(r.content)


speak(answer(transcribe("question.wav")), "reply.mp3")

转录响应是 JSON,其中 text 中为转录文本,usage 对象报告该请求的音频秒数和美元 cost。可将 openai/gpt-5-mini 替换为 目录 中的任意聊天模型,而无需改动音频调用,并保持相同的 voice,让代理听起来像第 1 步中的旁白。

第 3 步:将评审会议转化为带说话人标注的笔记

当你的团队开会评审导览时,Scribe v2 可以告诉你谁说了什么。以 multipart 形式上传录音,请求带词级时间戳的 verbose_json,并在 provider.options.elevenlabs 下设置 diarize。这样响应中的每个词都会带有说话人。如果你知道会议中有多少人,请传入 num_speakers 以改进分离效果。

curl https://openrouter.ai/api/v1/audio/transcriptions \
  --fail-with-body \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -F file="@tour-review.mp3" \
  -F model="elevenlabs/scribe-v2" \
  -F response_format="verbose_json" \
  -F "timestamp_granularities[]=word" \
  -F provider='{"options": {"elevenlabs": {"diarize": true, "num_speakers": 3, "tag_audio_events": true}}}'

words 中的每个条目都有 word、start、end、confidence、speaker(一个整数)和 speaker_label(speaker_0、speaker_1 等)。tag_audio_events 会在词之外添加诸如 (laughter) 之类的条目。按 speaker 对连续词进行分组以得到发言轮次,然后将这些轮次发送给聊天模型以生成摘要和行动项:

def to_turns(words: list[dict]) -> list[str]:
    turns: list[tuple[int, list[str]]] = []
    for w in words:
        if turns and turns[-1][0] == w.get("speaker"):
            turns[-1][1].append(w["word"])
        else:
            turns.append((w.get("speaker"), [w["word"]]))
    return [f"Speaker {s}: {' '.join(ws)}" for s, ws in turns]

上传文件上限为 25 MB,大约相当于 27 分钟的 128 kbps MP3。

对于更长的录音,传入一个公开 URL,ElevenLabs 会直接下载该文件,因此 25 MB 的上限不适用:

"input_audio":{ "url": "https://example.com/tour-review.mp3" }

非常长的文件仍可能触及 180 秒的上游请求超时,因此请拆分过长的录音。

首次请求的提示

  1. 按名称或 ID 选择语音。 对于 voice,可按名称传入 ElevenLabs 的 21 种预制语音中的任意一种:george、sarah、adam、alice、bella、brian、charlie、daniel、jessica、roger、will 等等(完整列表见各模型页面)。 名称不区分大小写。要使用任何其他语音,请将其 ElevenLabs 语音 ID 作为 voice 传入——可从 ElevenLabs 语音库 复制。 你克隆或设计的语音存在于你自己的 ElevenLabs 账户中,因此请通过 BYOK 使用它们。
  2. 当你想要可播放的文件时,请请求 mp3 如果省略 response_format,我们的语音端点会返回原始 PCM(24 kHz 的 16 位小端单声道)。这适合音频流水线,但大多数播放器无法打开它。设置 "response_format": "mp3" 可获得可播放的 44.1 kHz、128 kbps 文件。
  3. 使用 Multilingual v2 或 Flash 进行速度控制 Multilingual v2 和 Flash 接受 speed 从 0.7 到 1.2。Eleven v4 和 v4 Turbo 没有速度控制,并会拒绝非默认的 speed,因此在这些模型上请省略它,而改用音频标签来改变节奏。
  4. 拆分长脚本 每个模型都有单次请求的字符限制(见模型表)。音频标签会计入该限制,也会计入你的计费字符数。像第 1 步那样按段落边界拆分,并传入 previous_text 和 next_text,让衔接听起来自然。
  5. ElevenLabs 专属设置放在 provider.options.elevenlabs 下 Text to Speech 接受 seed、previous_text、next_text、language_code、apply_text_normalization、apply_language_text_normalization、pronunciation_dictionary_locators、voice_settings(stability、similarity_boost、style、use_speaker_boost、speed)以及 output_format(ElevenLabs 格式名称,例如 mp3_22050_32 或 pcm_16000;它必须与你的 response_format 编解码器匹配)。Speech to Text 接受 diarize、num_speakers、diarization_threshold、tag_audio_events、no_verbatim 和 seed。num_speakers 和 diarization_threshold 需要 diarize: true,且你只能设置其中之一,不能同时设置。请严格按所列名称使用字段名。不在这些列表中的键会被忽略;列表中的键若值无效会返回 400。
  6. Scribe 返回三字母语言代码 你可以发送两字母的 language 提示(en)。检测到的语言会以 ISO 639-3 代码返回(eng)。

快速开始

  1. 创建一个 OpenRouter API key。
  2. 使用上文第 1 步中的 curl 示例发出你的第一个请求。
  3. 关于每个参数,请参阅 Text to Speech 和 Speech to Text 指南。

Text to Speech 按输入字符计费,以 Unicode 码点计数,因此一个 emoji 或一个 CJK 字符计为一次。音频标签也计为字符。Scribe 按音频秒数计费,每个转录响应中的 usage.cost 字段会告诉你该请求的费用。我们按 ElevenLabs 定价原样传递,不加价;当前费率请查看各模型页面。

已经有 ElevenLabs 账户?

通过 BYOK 添加你的密钥,以使用你自己克隆的声音、发音词典以及更高质量的格式,例如 mp3_44100_192。

创建一个 OpenRouter API key,或先在 Playground 中试用模型。Text to Speech 和 Speech to Text 指南包含完整的请求参考。

来源:OpenRouter Blog · openrouter.ai