@crvouga/mockingbird-service-elevenlabs

中文文档
0.10.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 3118

本地"11Labs"的文本对语音模拟器:可解码的MP3和原始的PCM答案,脚本音频回复,供应商错误信封和编辑调用元数据而不进行计费合成.

中文使用文档
文档目录13 节
  1. 安装
  2. 使用量
  3. 路线
  4. 音频
  5. 错误
  6. 脚本
  7. 电话和指纹
  8. 管理员(超过标准合同)
  9. 命名空间
  10. 存储什么
  11. 现场平等
  12. 故意不模拟
  13. API 密码

@crvouga/mockingbird-service-elevenlabs (英语)

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

模拟器 十一Labs 文本为语音 测试套房: POST /v1/text-to-speech/{voice_id} 用音频回答,真的 output_format 说(可解码的 MPEG 第 三层框架, 无头 PCM 样本,或 WAV 文件),带有销售商的错误信封,以及精确的字节 测试队列。 无一物被模型合成,无一物被计费:默认的音频是a 音调,其音调和音长是请求的函数.

  • 行动范围: 支助
  • 状态 : 进行中的工作. 没有供应商证书,因此有几项答复 (a) 供应商的文件未经现场检查 未核实 下级 错误 财务报告和审定财务报表 音频。 。 。 .

安装

npm install -D @crvouga/mockingbird-service-elevenlabs

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 npx mockingbird-elevenlabs serve, (中文(简体) ), createServer 从 ./server (节点),或 createRuntime 与任何获取服务器.

使用量

在模拟器上指向该应用的"11Labs"基础 URL(http://127.0.0.1:8841/v1 真实的 一个是 https://api.elevenlabs.io/v1并赋予它仿真者所接受的密钥.

npx mockingbird-elevenlabs serve --port 8841 \
  --api-key "$ELEVENLABS_API_KEY" \
  --voices "$ELEVENLABS_VOICE_ID" \
  --models eleven_multilingual_v2,eleven_flash_v2_5

在进程中,通过模拟器作为 fetch 官方 SDK (中文(简体) )@elevenlabs/elevenlabs-js:

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js"
import {
  createRuntime,
  DEFAULT_API_KEY,
  DEFAULT_VOICES,
  mp3Audio,
} from "@crvouga/mockingbird-service-elevenlabs"

// Test setup. A reply the test controls: exact bytes for one text. Here they are a valid MP3,
// but any bytes are returned as given.
const scripted = mp3Audio(44_100, 128, 500, 9)
const emulator = createRuntime({
  scripts: [{ match: { text: "Welcome back." }, audio: scripted }],
})

// The ElevenLabs SDK your application already uses. Only its fetch changes: requests reach
// the emulator in this process instead of api.elevenlabs.io.
const elevenlabs = new ElevenLabsClient({
  apiKey: DEFAULT_API_KEY,
  fetch: ((url: RequestInfo | URL, init?: RequestInit) =>
    emulator.fetch(new Request(url, init))) as typeof fetch,
})
const voiceId = DEFAULT_VOICES[0]?.voice_id ?? ""

const welcome = await elevenlabs.textToSpeech
  .convert(voiceId, { text: "Welcome back.", modelId: "eleven_multilingual_v2", outputFormat: "mp3_44100_128" })
  .withRawResponse()
console.log(welcome.rawResponse.status, welcome.rawResponse.headers.get("content-type")) // 200 audio/mpeg
console.log((await new Response(welcome.data).arrayBuffer()).byteLength === scripted.length) // true

// Unscripted requests get generated audio: raw 16-bit mono samples for pcm_44100.
const pcm = await elevenlabs.textToSpeech.convert(voiceId, { text: "Anything else.", outputFormat: "pcm_44100" })
console.log((await new Response(pcm).arrayBuffer()).byteLength) // 61740

路线

路线行为
POST /v1/text-to-speech/{voice_id}?output_format=…贾森 {text, model_id?} 与 xi-api-key答复 200 带音频和信头 character-cost (代码: text, (中文(简体) ), request-id 财务报告和审定财务报表 x-trace-id。 。 。 . output_format 默认为 mp3_44100_128 财务报告和审定财务报表 model_id 改为 eleven_multilingual_v2就像卖家一样 这个 Accept 页眉不读.

该路径上的任何其他方法是: 405 {"detail": "Method Not Allowed"} 与 allow: POST; 任意 其他路径是 404 {"detail": "Not Found"}。 。 。 .

音频

请求由最老排队者回答 脚本 这匹配它。 没有一个人 模拟器生成一个音调: 每个字符50ms text (至少0.25 s, 最多5 s), 1 从请求中挑选的十二个投出 指纹。同样的 因此,无论何时,请求总是得到相同的字节,以及两个不同的请求 几乎总是得到不同的文本(两个相同长度的文本,当它们降落在 相同的投出; 当测试需要绝对不同的字节时排入脚本 .

output_format字节content-type
mp3_44100_32, (中文(简体) ), _64, (中文(简体) ), _96, (中文(简体) ), _128, (中文(简体) ), _192MPEG-1 第III层,44.1 kHz,单相,常位速率. 每个字节都属于一个完整的1152个样板框架;被粘贴的比特保持了流的标称速率(417-和418个字节框架以128克比特/秒). 没有ID3标记,没有星头.audio/mpeg
mp3_22050_32, (中文(简体) ), mp3_24000_48MPEG-2 第III层,单相,576-样相框.audio/mpeg
pcm_8000 . pcm_48000Raw签下16位小endian单样. 没有容器和头:第一个字节是第一个样本.audio/pcm (单位:千美元)未核实(中文(简体) )
wav_8000 . wav_48000犬科44字节RIFF/WAVE头后面的同样样本.audio/wav (单位:千美元)未核实(中文(简体) )
opus_48000_*, (中文(简体) ), ulaw_8000, (中文(简体) ), alaw_8000未生成. 501 与 detail.type: "mockingbird_not_modelled" 直到脚本提供字节;然后 audio/opus, (中文(简体) ), audio/basic, (中文(简体) ), audio/x-alaw-basic (单位:千美元)未核实) (中文(简体) ).

pcm_44100 不是WAV文件,不管请求是什么 Accept 信头写着: 发送的客户端 Accept: audio/wav 并将答案作为WAV从小贩那里得到的无头样本 从这个模范一样。 问 wav_44100 去拿货柜.

MP3帧携带真实的音频,而不是填充器前的页眉:每个颗粒Huffman-code 一个光谱线,和 ffmpeg, (中文(简体) ), mpg123 和 Core 音频解码流到稳定音调 大约四分之一的全尺寸. mp3Audio, (中文(简体) ), pcmAudio 财务报告和审定财务报表 wavAudio 为建筑物导出 属于有效音频的脚本定着.

销售商的参考文献说明和模拟者如下: 格式列表 mp3_44100_128 默认, audio/mpeg,而PCM作为S16LE,深度为16位. 没有说, 如此未经证实:除了 audio/mpeg;PCM和MP3是单体的( 引用时只表示拒绝“制作立体声”的效果 pcm_*页:1 页眉布局; 真实的 MP3 答案是否从 ID3 标记开始; 以及 character-cost 等于 每个模型的字符数.

错误

除了一个错误 422 是卖家的信封,与 x-trace-id 重复 request_id数字 :

{
  "detail": {
    "type": "authentication_error",
    "code": "unauthorized",
    "message": "Invalid API key",
    "status": "invalid_api_key",
    "request_id": "8d3fefe1da6d251e5b571c484eecdaad"
  }
}

status 是遗留的标识符( 供应商仍然发送; 老客户端已读取) detail.status 财务报告和审定财务报表 detail.message) (中文(简体) ). param 当一个请求参数出现过错时会添加. A 类 422 是请求验证器的列表 : {"detail": [{"type", "loc", "msg", "input"}]}。 。 。 .

请求答复依据
身体不是JSON的,不是JSON422 json_invalid, (中文(简体) ), loc: ["body", 0], (中文(简体) ), msg: "JSON decode error"被观察. 卖家的 loc[1] 是解析器的字符偏移和 ctx.error 其信息;模拟者发送 0 财务报告和审定财务报表 "Invalid JSON"。 。 。 .
没有尸体,非JSON媒体类型,或者没有 text422 missing, (中文(简体) ), loc: ["body", "text"], (中文(简体) ), msg: "Field required"被观察. 对于一个JSON阵列,供应商将每个体域列为缺失;模拟器列表 text。 。 。 .
text 或者说 model_id 不是一个字符串422 string_type, (中文(简体) ), msg: "Input should be a valid string", (中文(简体) ), input 值被观察.
没有 xi-api-key401 authentication_error 编号 : unauthorized, (中文(简体) ), status: "needs_authorization"观察,信息包含.
命名空格没有按键401 authentication_error 编号 : unauthorized, (中文(简体) ), status: "invalid_api_key"观察,信息包含.
output_format 未列入供应商名单400 validation_error 编号 : invalid_output_format, (中文(简体) ), param: "output_format"有记录的代码和类型. 未核实 在电线上.
text 实值 ""400 validation_error 编号 : empty_text, (中文(简体) ), param: "text"有记录的代码和类型. 未核实 在电线上.
未配置的声音404 not_found 编号 : voice_not_found, (中文(简体) ), param: "voice_id"有记录的代码和类型. 未核实; 供应商的更年长的帮助文章文件 voice_not_found 在"400或401"下.
未配置的模型404 not_found 编号 : model_not_found, (中文(简体) ), param: "model_id"有记录的代码和类型. 未核实 在电线上.
配置的模型 can_do_text_to_speech: false400 validation_error 编号 : unsupported_model有记录的代码和类型. 未核实 在电线上.

"Observed"是指公众端点给出的请求没有API密钥的答案,或者一个 编成一,于2026-10-10查阅. 这些答案还确定了头两次检查的顺序:身体 在检查密钥之前验证( 带坏身体的无密钥请求是) 422页:1 键前 output_format,文本和语音(格式未知的无密钥请求为 401) (中文(简体) ). 钥匙后面的检查顺序是 未核实:格式,空文本,语音, 型号。 对于未经核实的行 message 是供应商错误中的描述 参考, status 重复 code,以及供应商是否发送 param 不详.

脚本

POST /__admin/scripts 请求的队列精确字节 a match 选择 :

{
  "match": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "output_format": "mp3_44100_128", "text": "Welcome back." },
  "audio_base64": "//uQwAAAACALlACEIAAEAXKA…",
  "content_type": "audio/mpeg",
  "times": 1
}
  • match 可能名称 voice_id, (中文(简体) ), model_id, (中文(简体) ), output_format,准确的 text 联合国 text_sha256),以及整个请求 fingerprint。每个给定的字段必须匹配;空 match 回答每一个请求. text 到达时就散了.
  • times 在许多答案后退出脚本;没有这些答案,脚本将回答每个 匹配请求,这是缓存测试想要的。 在最古老的剧本中 答题左取胜,所以在重复之前先排队一发答题.
  • 一个脚本只被一个否则会得到音频的请求所使用. 请求被驳回 4xx或因过错而失败 让它不受影响.
  • content_type 覆盖格式的内容类型.
  • 这个 scripts 选项 createRuntime 形状一样 audio: Uint8Array这些 脚本由 POST /__admin/reset;在 HTTP 上排队的脚本被它丢出.

电话和指纹

仿真器每处理一个请求 保存一个记录 它处理过去的身体验证, 没有请求 文本 : GET /__admin/calls 答题 {count, by_fingerprint, calls}每次通话 {id, voice_id, model_id, output_format, text_sha256, text_characters, fingerprint, status, error, script_id, audio_bytes, audio_sha256, content_type, at}。 。 。 . ?fingerprint=<hex> 缩进 给一个请求.

  • text_sha256 是 UTF-8 文本的 SHA-256(textFingerprint(text)) (中文(简体) ).
  • fingerprint 是 JSON 阵列的 SHA-256 [voice_id, model_id, output_format, text_sha256] 与已填入的缺省数(speechFingerprint({voice_id, model_id?, output_format?, text})) (中文(简体) ). 其他身体领域不是它的一部分.

请求因过失而失败,从未到达模拟者那里,所以他们没有通话记录 请求日记( e)GET /__admin/requests具有其地位和 faultId。 。 。 .

管理员(超过标准合同)

路线效果
POST /__admin/scripts请回答(上). 201 与 {id, match, content_type, bytes, sha256, times, remaining, hits}· ; 400 与一个错误的脚本的原因.
GET /__admin/scripts取名空间的脚本,最古老的第一,没有他们的音频.
DELETE /__admin/scripts放下每个脚本. {deleted}。 。 。 .
GET /__admin/calls调用记录和计数(上).
PUT /__admin/voices{voices: ["<id>", {voice_id, name?}]} 替换命名空间的声音. GET 列出他们.
PUT /__admin/models{models: ["<id>", {model_id, can_do_text_to_speech?}]} 替换命名空间的模型. GET 列出他们.
PUT /__admin/keys{keys: ["<key>"]} 替换命名空间接受的密钥. GET 列出他们的SHA -256, 从来没有键.

名称空间从密钥开始 fixture-elevenlabs-key,声音 21m00Tcm4TlvDq8ikWAM (单位:千美元) 和模型 eleven_multilingual_v2, (中文(简体) ), eleven_flash_v2_5 财务报告和审定财务报表 eleven_turbo_v2_5,除非 keys, (中文(简体) ), voices 财务报告和审定财务报表 models 选项另作说明. POST /__admin/reset 返回到这个位置,以及 POST /__admin/snapshots 及其恢复盖 脚本(并附有剩余答案)和呼叫记录.

错误预设( E)POST /__admin/faults/presets/<name>数字 {"count": n} 失败超过 下一个请求; GET /__admin/faults/presets) (中文(简体) ). 每个答案在模拟器前,所以 记录没有调用, 没有使用脚本 :

预设答复
invalid_api_key401 authentication_error, (中文(简体) ), status: "invalid_api_key"
quota_exceeded402 payment_required 编号 : insufficient_credits, (中文(简体) ), status: "quota_exceeded"
rate_limited429 rate_limit_error 编号 : rate_limit_exceeded
too_many_concurrent_requests429 rate_limit_error 编号 : concurrent_limit_exceeded, (中文(简体) ), status: "too_many_concurrent_requests"
system_busy429 rate_limit_error 编号 : system_busy
server_error500 internal_error
service_unavailable503 service_unavailable
network_reset无回答: 连接被丢弃( N)fetch 拒绝方式 TypeError) (中文(简体) ).
slow_response请求在模拟者看到前被持有250毫秒.

情况、类型和代码是供应商错误参考清单 未遵守(未核实) (中文(简体) ). 具体地说,该参考文献指出: 402, (中文(简体) ), 卖家年长的帮助文章文件 quota_exceeded 在"400或401"下。 对于任何其他 身份或机构,增加一条规则: POST /__admin/faults {"status": 401, "count": 1, "body": {…}}。 。 。 . {"latencyMs": n} 请求由 n 毫秒; 通过 io: {sleep} 改为 createRuntime 改为 让它虚拟地等待。 当等待结束时, 请求被挡在后面时中止 .

命名空间

一个命名空间有自己的键,声音,模型,脚本和呼叫记录. 选择一个与 x-mockingbird-namespace 标题,带有 /__admin/ns/<name> 基础 URL 前缀 (单位:千美元)http://127.0.0.1:8841/__admin/ns/worker-1/v1),或用 API 键: PUT /__admin/credentials {"credentials": {"<key>": "<namespace>"}},在将该密钥添加到 名称空间 PUT /__admin/keys。 。 。 .

存储什么

请求文本、 API 密钥和音频永远不能到达日记、 日志、 状态反省、 状态 管理路线或快照。 请求留下一份识别资料、长度和摘要的呼叫记录; 一个密钥作为SHA-256保存; 脚本音频被加密(AES-256-GCM在密钥下) 仅存在于此过程中; 通过 vaultKey 重开一个持续的数据库) 还有SHA-256 被否决的身体被记录为字段和原因,绝不是价值.

现场平等

bun run parity:service -- elevenlabs 比较模拟器和真实的 API。 这需要 ELEVENLABS_API_KEY 2号出口没有它。 默认情况下,它只发出供应商的请求 在合成前拒绝(无效的正文,一个不存在的语音),所以没有字符 计费; --include-unsafe 增加一条短线的转换 ELEVENLABS_VOICE_ID该 运行是解开上面标有的行.

故意不模拟

  • 出自"语义"的语音:音是声调,从来不说. 需要特别测试 音频队列.
  • 流言(/stream, WebSockets),时间戳(/with-timestamps),文本为对话框.
  • 语音克隆和语音管理/v1/voices),型号上市(/v1/models: 声音 模型是通过管理路线设置的固定装置.
  • 接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接接.
  • 记帐,认购,定额和计划限额. 每个键都可以使用每一种格式 等级规则 mp3_44100_192 和44.1 kHz PCM,每个模型字符限制和真实 费率限额不适用。 使用断层预设以故意失败请求 .
  • 请求字段以外的 text 财务报告和审定财务报表 model_id (单位:千美元)voice_settings, (中文(简体) ), seed, (中文(简体) ), language_code, (中文(简体) ), previous_text,(...)和 enable_logging 财务报告和审定财务报表 optimize_streaming_latency 查询 参数: 已接受,未验证,且对答案或指纹没有影响.
  • Authorization 作为替代 xi-api-key,以及供应商的区域主机.
  • Opus、mu-law和A-law编码(仅标注,见 音频) (中文(简体) ).

API 密码

导出仁爱说明
ElevenLabsAPI类进程模拟器 : fetch(request), (中文(简体) ), reset(), (中文(简体) ), queue(script), (中文(简体) ), scripts(), (中文(简体) ), clearScripts(), (中文(简体) ), calls()选项: sqlite, (中文(简体) ), now, (中文(简体) ), namespace, (中文(简体) ), keys, (中文(简体) ), voices, (中文(简体) ), models, (中文(简体) ), scripts, (中文(简体) ), vaultKey。 。 。 .
createRuntime函数全面服务合同的仿真器(保健、管理、命名空间、证书、预设和日记)。 备选方案: ElevenLabsAPI 加号 clock, (中文(简体) ), seed, (中文(简体) ), adminPrefix, (中文(简体) ), adminKey, (中文(简体) ), onLog, (中文(简体) ), io。 。 。 .
ELEVENLABS_PRESETS对象每个命名的断层预设.
ELEVENLABS_NAMESPACE字符串服务名称, "elevenlabs"。 。 。 .
API_KEY_HEADER字符串"xi-api-key"。 。 。 .
DEFAULT_API_KEY, (中文(简体) ), DEFAULT_VOICES, (中文(简体) ), DEFAULT_MODELS, (中文(简体) ), DEFAULT_MODEL_ID数值命名空间始于什么, 当请求命名为无时所使用的模型 .
OUTPUT_FORMATS, (中文(简体) ), DEFAULT_OUTPUT_FORMAT数值每个 output_format 供应商名单,以及 "mp3_44100_128"。 。 。 .
describeFormat函数(format) 改为 {codec, sampleRate, bitrate?, contentType, synthesized}。 。 。 .
mp3Audio, (中文(简体) ), pcmAudio, (中文(简体) ), wavAudio函数调子产生器: mp3Audio(sampleRate, bitrate, durationMs, line), (中文(简体) ), pcmAudio(sampleRate, durationMs, line), (中文(简体) ), wavAudio(sampleRate, durationMs, line)时 line 选择投出(line + 0.5) * 38.28 Hz in PCM and WAV)). 互联网档案馆的存檔,存档日期2013-12-21.
speechFingerprint, (中文(简体) ), textFingerprint函数文摘中包含一个脚本匹配和呼叫记录.
createVaultKey函数一个新鲜的32字节键 vaultKey 选项.
document, (中文(简体) ), operationIds, (中文(简体) ), supportedOperationIds数值OpenAPI合同及其操作代号.
createServer, (中文(简体) ), serveTarget, (中文(简体) ), DEFAULT_PORT (单位:千美元)./server(中文(简体) )节点服务过来 node:http; 数据 serve CLI目标;出港8841.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-elevenlabs 共发布 20 个版本,首次发布于 2026/10/11;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.10.0latest2026/11/11今天
0.9.92026/11/038 天前
0.9.82026/11/038 天前
0.9.72026/11/038 天前
0.9.62026/11/038 天前
0.9.52026/11/038 天前

关于 @crvouga/mockingbird-service-elevenlabs 的常见问题

@crvouga/mockingbird-service-elevenlabs 是什么?

本地"11Labs"的文本对语音模拟器:可解码的MP3和原始的PCM答案,脚本音频回复,供应商错误信封和编辑调用元数据而不进行计费合成.

如何安装 @crvouga/mockingbird-service-elevenlabs?

在项目目录运行 npm install @crvouga/mockingbird-service-elevenlabs,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-elevenlabs,可以用 npx mockingbird-elevenlabs 直接运行。

@crvouga/mockingbird-service-elevenlabs 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-elevenlabs 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-elevenlabs 可以商用吗?

@crvouga/mockingbird-service-elevenlabs 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-elevenlabs 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-elevenlabs 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,118 次,日均约 104 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-elevenlabs 还在维护吗?

最新版本 0.10.0 发布于 2026/11/11(今天);至今共发布 20 个版本,其中过去 12 个月发布了 20 个;首次发布于 2026/10/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。