Dub into multiple languages

Add several target languages to a single project and download each dub.

How-to guide · Assumes you have created a dubbing project, as shown in the Dubbing quickstart.

A single project holds one source transcript, and you can add as many language targets as you need. Each language is generated independently and carries its own status and output, so you translate the source once and produce every dub from it.

Add several languages

Add one language target per language you want to dub into. Each starts in queued and begins generating once the project is ready.

import os
from dotenv import load_dotenv
from elevenlabs.client import ElevenLabs
load_dotenv()
elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))
project_id = "proj_1601kwkyxp0hfzvtmyxwqxx6mcy3"
target_languages = ["es", "fr", "de", "ja"]
languages = [
elevenlabs.dubbing.project.language.create(project_id, target_language=lang)
for lang in target_languages
]

You can also queue the first language when you create the project by passing target_language to project.create. Add any further languages with language.create as shown above.

Languages are specified as BCP-47 tags, for example es or fr-CA. See the supported languages and dialects for all accepted values.

Track each language independently

Languages generate in parallel and finish at different times. List the project’s languages to check the status of each, rather than polling them one by one.

import time
while True:
result = elevenlabs.dubbing.project.language.list(project_id)
pending = [l for l in result.languages if l.status in ("queued", "processing")]
if not pending:
break
print(f"{len(pending)} language(s) still generating...")
time.sleep(5)

Download every completed dub

Once a language reaches completed, its outputs.lossless_audio holds a signed download URL. Download each one, skipping any language that failed.

import requests
result = elevenlabs.dubbing.project.language.list(project_id)
for language in result.languages:
if language.status != "completed":
print(f"Skipping {language.target_language}: {language.status}")
continue
audio = requests.get(language.outputs.lossless_audio)
with open(f"dubbed_{language.target_language}.wav", "wb") as f:
f.write(audio.content)
print(f"Saved dubbed_{language.target_language}.wav")

Signed URLs expire about an hour after they are issued. If a download fails because the URL has expired, fetch the language again with language.get to obtain a fresh URL.

If a language fails to generate, add it again with language.create on the same project rather than creating a new project. The project and its transcript are reusable, so only the failed language is regenerated.