ElevenLabs Dubbing
將音訊或影片配音成其他語言,同時保留原始說話者的聲音。從檔案或 URL 創建專案、檢視和編輯原始轉錄稿、新增一個或多個目標語言、精煉每個片段的翻譯,並重新產生輸出。
重要事項: 使用 Dubbing Projects API — SDK 中的
elevenlabs.dubbing.project.*,或/v1/dubbing/projectREST 端點。請勿使用舊版 v1 dubbing 介面 (client.dubbing.create()、client.dubbing.get()、client.dubbing.audio.get()或裸/v1/dubbing路由) — 那是較舊的 dubbing API,現在在 API 參考文件中歸類為 Legacy。
設定: 請參閱安裝指南。REST 基礎 URL 為
https://api.elevenlabs.io,需在xi-api-key標頭中提供您的 API 金鑰;SDK 會自動讀取ELEVENLABS_API_KEY環境變數。
概念
| 概念 | 意義 |
|---|---|
| 專案 (Project) | 一個媒體來源(檔案或 URL)及其原始轉錄稿。準備(轉錄)一次後,即處於 ready 狀態,等待您新增語言。 |
| 原始轉錄稿 (Source transcript) | 從來源轉錄的可編輯片段(文字、說話者、時間戳)。這是每個語言翻譯所依據的單一事實來源。 |
| 語言 (目標) (Language / target) | 一個配音輸出語言。每個目標語言都有自己專屬的轉錄稿(來源片段 + 每個片段的翻譯)和配音音訊輸出。 |
| 修訂版次 (Revisions) | 獨立的單調遞增計數器。專案的 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 | 檔案/source_url 二選一 | 要配音的來源媒體(音訊或影片),最大 3 GiB |
source_url | 檔案/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 與來源相符)。編輯單一翻譯,然後重新產生。(僅限企業工作區。)
# 讀取語言的翻譯
target = 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 - 轉錄稿編輯 / 重新產生不可用:這些端點僅限企業方案 — 在其他方案上,請在創建專案時先確定來源已最終化,然後直接新增語言