Elevenlabs
v2通过使用 @runapi.ai/elevenlabs 的 Node/TypeScript SDK 与 RunAPI.ai 进行交互,生成和处理音频(文本转语音、多语音文本转对话、文本转音效、语音转文本、音频隔离)。当用户要求添加文本转语音、语音合成、语音转文本或文本转音效功能,或者提及 @runapi.ai/elevenlabs 时使用。触发关键词包括 "elevenlabs"、"text to speech"、"TTS"、"语音合成"、"speech-to-text"、"转录"、"text-to-sound"、"@runapi.ai/elevenlabs"。
运行时依赖
安装命令
点击复制技能文档
@runapi.ai/elevenlabs — RunAPI.ai Elevenlabs 音频生成
通过 RunAPI.ai 构建 Node / TypeScript 集成,生成语音、文本到对话、文本到声音、语音到文本和隔离音频。
设置
需要 Node 18+(全局 fetch)。
npm install @runapi.ai/elevenlabs
在环境中设置 API 密钥:
# .env
RUNAPI_API_KEY=runapi_xxx
# 获取一个 https://runapi.ai/api_keys
导入 { ElevenlabsClient } from '@runapi.ai/elevenlabs';
// SDK 从环境中自动读取 RUNAPI_API_KEY。
const client = new ElevenlabsClient();
如果您以不同的方式管理机密,请显式传递 { apiKey }。
baseUrl 默认为 https://runapi.ai;仅在本地开发时覆盖。
核心配方 — 文本到语音
const result = await client.textToSpeech.run({
model: 'text-to-speech-turbo-2-5',
text: 'Hello from RunAPI.',
voice: 'Rachel',
});
const audioUrl = result.audios[0].url;
run() 创建任务、自动轮询并仅在任务完成时解析 — audios[0].url 在解析值上是保证的(对于语音到文本,文本是保证的)。
在失败时抛出 TaskFailedError;在轮询超时时抛出 TaskTimeoutError。
对于脚本和短暂进程,请使用 run()。
对于请求处理程序,请分割它:
const { id } = await client.textToSpeech.create({
model: 'text-to-speech-turbo-2-5',
text: '...',
voice: 'Rachel'
});
// 立即返回 202;稍后获取:
const status = await client.textToSpeech.get(id);
if (status.status === 'completed') {
/ ... /
}
不要保持 Web 工作线程打开等待 run()。
分割 + webhook 是生产模式。
run() 默认每 2 秒轮询一次,持续 15 分钟。
根据需要调整:
await client.textToSpeech.run(params, {
maxWaitMs: 2 * 60_000,
pollIntervalMs: 1_000
});
如果 TaskTimeoutError 发生,任务仍在服务器端运行 — 使用 .get(id) 或通过 webhook 完成。
多语音对话
按行序列,每行语音:
const dialogue = await client.textToDialogue.run({
dialogue: [
{ voice: 'Rachel', text: 'So what did you think?' },
{ voice: 'Adam', text: 'Honestly, it was incredible.' },
],
stability: 0.5,
language_code: 'en',
});
console.log(dialogue.audios[0].url);
音效
const fx = await client.textToSound.run({
text: 'Thunderclap followed by rain on a tin roof',
duration_seconds: 6,
loop: false,
output_format: 'mp3_44100_128',
});
语音到文本(音频输入 -> 文本输出)
const t = await client.speechToText.run({
audio_url: 'https://cdn.example.com/meeting.mp3',
diarize: true,
tag_audio_events: true,
language_code: 'en',
});
console.log(t.text);
音频隔离(去除背景噪音)
const isolated = await client.isolateAudio.run({
audio_url: 'https://cdn.example.com/noisy.mp3',
});
console.log(isolated.audios[0].url);
模型
资源模型值
textToSpeech text-to-speech-turbo-2-5、text-to-speech-multilingual-v2
textToDialogue — (无模型字段;服务器选择引擎)
textToSound —
speechToText —
isolateAudio —
选择 turbo 模型以获得最低延迟;选择 multilingual v2 以获得非英语语音。
voice 接受 Elevenlabs 语音 ID 或命名语音(例如 'Rachel'、'Adam')。
确切的信用成本在 https://runapi.ai/pricing 和仪表板中显示 — 不要在应用程序代码中硬编码价格。
回调(webhook)
在 create()(或任何 run() 调用)上传递 callback_url,RunAPI 将最终有效负载 POST 到您:
await client.textToSpeech.create({
model: 'text-to-speech-turbo-2-5',
text: '...',
voice: 'Rachel',
callback_url: 'https://your.app/webhooks/runapi/elevenlabs',
});
有效负载形状(音频资源):
{ id: string; status: 'completed' | 'failed'; audios?: { url: string }[]; error?: string }
SpeechToText 返回 text: string 而不是 audios。
始终在信任正文之前验证签名。
RunAPI 使用您的帐户的回调密钥签署每个回调(在 /accounts/callback_secret 旋转)。
头部:
X-Callback-Id — UUID,存储以使处理程序幂等
X-Callback-Timestamp — Unix 秒,拒绝如果 |now - ts| > 300
X-Callback-Signature — base64 HMAC-SHA256 过 ${id}.${ts}.${rawBody} 使用 base64 解码的密钥
导入 crypto from 'node:crypto';
函数 verify(raw: string, id: string, ts: string, sig: string, secret: string) {
const key = Buffer.from(secret, 'base64');
const mac = crypto.createHmac('sha256', key)
.update(${id}.${ts}.${raw})
.digest('base64');
return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(sig));
}
在 10 秒内回复 2xx;任何非 2xx 触发重试。
错误
所有错误都从 @runapi.ai/core 中重新导出。
始终 instanceof — 从不字符串匹配消息。
错误 状态 操作
AuthenticationError 401 中止;显示“重新连接 API 密钥”
InsufficientCreditsError 402 提示用户在 runapi.ai/billing 中补充
ValidationError 400 / 422 修复参数;不要重试
RateLimitError 429 睡眠 err.retryAfterMs,然后重试
ServiceUnavailableError 503 / 455 重试带有退避;转换