ElevenLabs Dubbing (配音)
将音频或视频配音到其他语言,同时保留原始说话者的声音。从文件或 URL 创建项目,审查和编辑源转录,添加一个或多个目标语言,细化每个片段的翻译,然后重新生成输出。
重要提示: 请使用 Dubbing Projects API — SDK 中的
elevenlabs.dubbing.project.*,或 REST 端点/v1/dubbing/project。不要使用旧的 v1 配音界面(client.dubbing.create()、client.dubbing.get()、client.dubbing.audio.get()或裸的/v1/dubbing路由)—— 那是旧的配音 API,现已在 API 参考中标记为“Legacy”。
设置: 请参阅安装指南。REST 基础 URL 是
https://api.elevenlabs.io,在xi-api-key头中传递你的 API 密钥;SDK 会自动读取ELEVENLABS_API_KEY环境变量。
概念
| 概念 | 含义 |
|---|---|
| 项目 | 一个媒体源(文件或 URL)及其源转录。准备好(转录后)一次,然后处于 ready 状态等待添加语言。 |
| 源转录 | 从源媒体转录的可编辑片段(文本、说话者、时间戳)。每个语言翻译都基于此单一事实来源。 |
| 语言(目标) | 一个配音输出语言。每个目标语言都有自己的转录(源片段 + 每片段的翻译)和自己的配音音频输出。 |
| 修订版本 | 独立的单调递增计数器。项目的 revision 在源转录编辑时增加;语言的 revision 在其翻译编辑或受源编辑影响时增加。语言的 output_revision 是当前音频生成时的修订版本——当它落后于 revision 时,输出已过时。 |
推荐操作顺序: 在添加任何语言之前最终确定源转录。翻译是从源转录生成的,因此先纠正源文本意味着每种语言都从正确的文本开始——在语言完成后编辑源会使其标记为 stale,并需要(计费的)重新生成。
企业版: 转录编辑和重新生成仅对企业工作区可用。创建项目、添加语言和下载配音适用于所有计划。
工作流程
- 创建项目(从文件或 URL)→
queued - 轮询项目直到
ready - 审查并最终确定源转录(编辑/添加/删除片段)
- 添加一个目标语言 →
queued→processing→completed - 下载每个语言的
outputs.lossless_audio(当状态为completed时) - 细化每片段的翻译(如果需要)→ 该语言变为
stale - 重新生成该语言 → 再次变为
completed,并生成新的输出
快速开始 (Python)
import os
import time
import requests
from elevenlabs.client import ElevenLabs
elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))
# 1. 从本地文件创建项目(或者传递 source_url=... 替代文件)
with open("promo.mp4", "rb") as f:
project = elevenlabs.dubbing.project.create(
file=f,
source_language="en",
reference="Q3 marketing video",
)
# 2. 等待源媒体转录完成
while True:
project = elevenlabs.dubbing.project.get(project.project_id)
if project.status == "ready":
break
if project.status == "failed":
raise RuntimeError("Project preparation failed")
time.sleep(5)
# 3. 添加西班牙语目标语言
language = elevenlabs.dubbing.project.language.create(
project.project_id,
target_language="es",
)
# 4. 等待配音生成完成
while True:
language = elevenlabs.dubbing.project.language.get(
project.project_id, language.language_id
)
if language.status == "completed":
break
if language.status == "failed":
raise RuntimeError("Dub generation failed")
time.sleep(5)
# 5. 下载配音音频(签名 URL,有效期约 1 小时——重新获取语言对象以获得新的 URL)
audio = requests.get(language.outputs.lossless_audio)
with open("promo_es.wav", "wb") as f:
f.write(audio.content)
快速开始 (JavaScript)
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { writeFile } from "fs/promises";
const elevenlabs = new ElevenLabsClient();
// 1. 创建项目(此处演示 sourceUrl;也支持文件上传)
let project = await elevenlabs.dubbing.project.create({
sourceUrl: "https://example.com/promo.mp4",
sourceLanguage: "en",
reference: "Q3 marketing video",
});
// 2. 等待源媒体转录完成
while (true) {
project = await elevenlabs.dubbing.project.get(project.projectId);
if (project.status === "ready") break;
if (project.status === "failed") throw new Error("Project preparation failed");
await new Promise((resolve) => setTimeout(resolve, 5000));
}
// 3. 添加西班牙语目标语言
let language = await elevenlabs.dubbing.project.language.create(project.projectId, {
targetLanguage: "es",
});
// 4. 等待配音生成完成
while (true) {
language = await elevenlabs.dubbing.project.language.get(project.projectId, language.languageId);
if (language.status === "completed") break;
if (language.status === "failed") throw new Error("Dub generation failed");
await new Promise((resolve) => setTimeout(resolve, 5000));
}
// 5. 从签名 URL 下载配音音频
const response = await fetch(language.outputs!.losslessAudio!);
await writeFile("promo_es.wav", Buffer.from(await response.arrayBuffer()));
快速开始 (cURL)
# 1. 创建项目(使用 -F "source_url=https://..." 替代文件以从 URL 配音)
curl -X POST "https://api.elevenlabs.io/v1/dubbing/project" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-F "[email protected]" \
-F "source_language=en"
# → {"project_id": "proj_...", "status": "queued", ...}
# 2. 轮询直到状态为 "ready"
curl "https://api.elevenlabs.io/v1/dubbing/project/proj_..." \
-H "xi-api-key: $ELEVENLABS_API_KEY"
# 3. 添加目标语言
curl -X POST "https://api.elevenlabs.io/v1/dubbing/project/proj_.../language" \
-H "xi-api-key: $ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"target_language": "es"}'
# 4. 轮询语言直到 "completed",然后下载 outputs.lossless_audio
curl "https://api.elevenlabs.io/v1/dubbing/project/proj_.../language/lang_..." \
-H "xi-api-key: $ELEVENLABS_API_KEY"
创建选项
POST /v1/dubbing/project 接受 multipart/form-data,其中要么包含 file 要么包含 source_url(不能同时包含):
| 字段 | 必需性 | 说明 |
|---|---|---|
file | file/source_url 二选一 | 要配音的源媒体(音频或视频),最大 3 GiB |
source_url | file/source_url 二选一 | 从公共 URL 获取源媒体 |
source_language | 否 | ISO 639 代码(例如 en)。留空则自动检测——检测到的语言将在源转录的 language 字段中报告 |
reference | 否 | 自由格式标签,用于您自己标识项目(最多 500 个字符) |
model_id | 否 | dubbing_v2(默认) |
target_language | 否 | 可选,在创建时立即启动第一个语言目标;更多语言可通过 language.create 添加 |
keyterms | 否 | 偏向转录/翻译的术语(产品/品牌名称)。最多 100 个术语,每个 200 个字符;在 multipart 中每次重复该字段一个术语 |
编辑源转录
项目状态变为 ready 后,读取转录,然后在添加语言之前进行纠正。每次编辑都会增加项目的 revision。每个片段都有一个稳定的 id,用于编辑或删除它。(仅限企业工作区。)
# 读取源转录
transcript = elevenlabs.dubbing.project.transcript.get(project_id)
# 纠正片段的文本——仅发送要更改的字段(text, speaker_id, start_s, end_s)
elevenlabs.dubbing.project.transcript.update_segment(
project_id,
segment_id=transcript.segments[0].id,
text="Welcome to our latest product demo.",
)
# 添加一个片段(重用现有的 speaker_id,以便用该说话者的声音配音)
added = elevenlabs.dubbing.project.transcript.create_segment(
project_id,
text="Thanks for watching.",
speaker_id=transcript.segments[0].speaker_id,
start_s=40.0,
end_s=42.0,
)
# 删除一个片段
elevenlabs.dubbing.project.transcript.delete_segment(project_id, segment_id=added.segment.id)
通过 REST:GET /v1/dubbing/project/{project_id}/transcript,然后 PATCH .../transcript/segment/{segment_id},仅包含更改的字段:
curl -X PATCH "https://api.elevenlabs.io/v1/dubbing/project/{project_id}/transcript/segment/{segment_id}" \
-H "xi-api-key: $ELEVENLABS_API_KEY" -H "Content-Type: application/json" \
-d '{"text": "Welcome to our latest product demo."}'
细化翻译并重新生成
语言的转录将每个源片段与其 translation 配对(null = 尚未翻译;片段 ID 与源匹配)。编辑单个翻译,然后重新生成。(仅限企业工作区。)
# 读取语言的翻译
目标 = elevenlabs.dubbing.project.language.transcript.get(project_id, language_id)
# 细化单个翻译(传递 translation=None 以清除翻译并标记为重新翻译)
elevenlabs.dubbing.project.language.transcript.update_segment(
project_id,
language_id,
segment_id=target.segments[0].id,
translation="Bienvenido a nuestra última demostración de producto.",
)
# 根据当前转录重新生成配音(按生成计费)
elevenlabs.dubbing.project.language.transcript.regenerate(project_id, language_id)
通过 REST:PATCH /v1/dubbing/project/{project_id}/language/{language_id}/transcript/segment/{segment_id},传递 {"translation": "..."},然后 POST .../language/{language_id}/transcript/regenerate(返回 202 Accepted)。
翻译编辑仅影响该语言。编辑后,状态为 completed 的语言变为 stale——它会继续提供之前的输出,直到您重新生成。轮询直到状态变为 completed;此时 output_revision 等于 revision,并且 outputs.lossless_audio 反映当前转录。
配音成多种语言
每种语言添加一个目标语言——每个独立生成。使用 language.list 跟踪所有语言,而不是逐个轮询:
for lang in ["es", "fr", "de", "ja"]:
elevenlabs.dubbing.project.language.create(project_id, target_language=lang)
while True:
result = elevenlabs.dubbing.project.language.list(project_id)
if not any(l.status in ("queued", "processing") for l in result.languages):
break
time.sleep(5)
状态
项目:
| 状态 | 含义 |
|---|---|
queued | 已创建;源获取和准备已入队 |
preparing | 正在准备(转录中) |
ready | 源转录可用;可以添加/生成语言。项目保持 ready 状态——每种语言的进度由语言层管理 |
failed | 准备失败(例如无法获取或解码源) |
语言:
| 状态 | 含义 |
|---|---|
queued | 等待项目变为 ready,或等待生成工作线程 |
processing | 配音正在生成 |
completed | 已完成;outputs 字段包含一个签名下载 URL(有效期约 1 小时——重新获取语言对象以获得新的 URL) |
stale | 先前已完成,但转录已更改;在重新生成之前保留上次输出 |
failed | 生成失败 |
您可以在项目变为 ready 之前添加语言——它将保持 queued 状态,并在项目变为 ready 后自动开始。添加语言时可选的 model_id(默认使用项目的模型)和 voice_settings(例如 {"cloning_strength": 7},范围 0–10,默认 7——控制配音说话者克隆源声音的强度)。
错误处理
- 401:API 密钥无效
- 409 Conflict(重新生成时):项目未处于
ready状态或语言未稳定(例如正在生成中)——等待后重试 - 过期的下载 URL:
outputs.lossless_audio已签名,有效期约 1 小时;重新获取语言对象以获得新的 URL - 转录编辑/重新生成不可用:这些端点仅限企业——在其他计划上,请使用已最终确定的源创建项目并直接添加语言