OpenRouter Blog更新于

ElevenLabs 现已登陆 OpenRouter

ElevenLabs 现已登陆 OpenRouter,提供 9 个 Text to Speech 模型和 2 个 Speech to Text 模型。使用 Eleven v4 交付富有类人情感的语音,借助 v4 Turbo 为你的智能体提供低延迟回复,并用 Scribe v2 将会议转化为能显示谁在发言的笔记。以下是应选择哪个模型,以及一个从零构建到完成的项目。

配图来源 · OpenRouter Blog

ElevenLabs 现已登陆 OpenRouter,提供九个 Text to Speech 模型和两个 Speech to Text 模型。

如果你的应用已经通过 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 标价 50% 的折扣

该选用哪个模型

从三个模型开始,当任务需要时再使用其余模型:

  • 旁白、角色配音、产品视频: Eleven v4。音频标签让脚本自带表演效果。
  • 语音智能体和实时回复: Eleven v4 Turbo,ElevenLabs 专为实时使用而打造,费率为 v4 的一半。
  • 转录稿、会议笔记、字幕: Scribe v2,提供说话人标签和词级时间戳。

当长篇音频需要语速控制时使用 Multilingual v2,而 Flash v2.5 则适用于每次请求最多 40,000 字符的高吞吐量语音。Scribe v2 Medical 针对医学术语进行了微调。

Text to Speech

模型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 的 Realtime 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 带单词级时间戳,并在 diarize 下设置 provider.options.elevenlabs。响应中的每个单词都会携带说话人。如果你知道会议中有多少人,传入 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 上传上限为 25 MB,大约覆盖 27 分钟的 128 kbps MP3。

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 秒的上游请求超时,因此请拆分运行时间过长的录音。

按名称或 ID 选择一个声音。

  1. 对于 ,可按名称传入 ElevenLabs 的 21 个预制声音中的任意一个: 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(16 位、24 kHz、单声道、小端序)。这适合音频处理流程,但大多数播放器无法打开它。请设置 "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 文本转语音功能接受 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 按输入字符计费,以 Unicode 码点计算,因此一个表情符号或一个 CJK 字符计为一次。音频标签也计为字符。Scribe 按音频秒数计费,每次转录响应中的 usage.cost 字段会告诉你该请求的费用。我们原样转发 ElevenLabs 定价,不加价;当前费率请查看各模型页面。

已经有 ElevenLabs 账户了?

使用以下方式添加你的密钥 BYOK 即可使用你自己的克隆语音、发音词典以及 mp3_44100_192 等更高质量的格式。

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

原始出处

OpenRouter Blog

内容说明

原始发布及相关权利归来源方。

机器翻译 · 请以原文为准