Dub audio and video files into different languages with AI-powered voice synthesis, transcript management, and multi-language support. Perfect for localizing content while maintaining voice characteristics and emotional delivery.
Related Documentation: To retrieve and download completed dubbing audio files, see the History API documentation for accessing generated audio.
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Access this API via: client.dubbingDub audio or video file into target language(s).
/**
* @param request - Media file and dubbing configuration
* @param requestOptions - Optional request configuration
* @returns Dubbing job ID and status
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.create(
request: BodyDubAVideoOrAnAudioFileV1DubbingPost,
requestOptions?: RequestOptions
): HttpResponsePromise<DoDubbingResponse>;
interface BodyDubAVideoOrAnAudioFileV1DubbingPost {
/** Audio or video file to dub */
file?: File | Blob;
/** Source file URL (alternative to file upload) */
source_url?: string;
/** Target language code(s) */
target_lang: string | string[];
/** Source language code (optional, auto-detected if not provided) */
source_lang?: string;
/** Number of speakers (1-10, optional for auto-detection) */
num_speakers?: number;
/** Whether to watermark free-tier dubs */
watermark?: boolean;
/** Start time in seconds */
start_time?: number;
/** End time in seconds */
end_time?: number;
/** Highest resolution output */
highest_resolution?: boolean;
/** Whether content is dubbed for video */
dubbing_studio?: boolean;
}
interface DoDubbingResponse {
/** Unique dubbing job ID */
dubbing_id: string;
/** Expected duration in seconds */
expected_duration_sec?: number;
}List accessible dubbing projects with filtering and pagination.
/**
* @param request - List filters and pagination
* @param requestOptions - Optional request configuration
* @returns Paginated list of dubbing projects
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.list(
request?: DubbingListRequest,
requestOptions?: RequestOptions
): HttpResponsePromise<DubbingMetadataPageResponseModel>;
interface DubbingListRequest {
/** Pagination cursor */
cursor?: string;
/** Page size (default: 100) */
pageSize?: number;
/** Filter by dubbing status */
dubbingStatus?: "dubbing" | "dubbed" | "failed";
/** Filter by creator */
filterByCreator?: "personal" | "workspace";
/** Sort field */
orderBy?: "created_at" | "name";
/** Sort direction */
orderDirection?: "ASCENDING" | "DESCENDING";
}
interface DubbingMetadataPageResponseModel {
/** Array of dubbing projects */
dubbings: DubbingMetadata[];
/** Next page cursor */
next_cursor?: string;
/** Whether more results exist */
has_more: boolean;
}
interface DubbingMetadata {
dubbing_id: string;
name?: string;
status: "dubbing" | "dubbed" | "failed";
target_languages: string[];
source_language?: string;
error?: string;
}Get metadata for a specific dubbing project.
/**
* @param dubbing_id - Dubbing project ID
* @param requestOptions - Optional request configuration
* @returns Dubbing project metadata
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.get(
dubbing_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<DubbingMetadataResponse>;
interface DubbingMetadataResponse {
dubbing_id: string;
name?: string;
status: "dubbing" | "dubbed" | "failed";
target_languages: string[];
source_language: string;
num_speakers?: number;
expected_duration_sec?: number;
time_dubbed_sec?: number;
error?: string;
}Delete a dubbing project by ID.
/**
* @param dubbing_id - Dubbing project ID
* @param requestOptions - Optional request configuration
* @returns Deletion confirmation
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.delete(
dubbing_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<DeleteDubbingResponseModel>;
interface DeleteDubbingResponseModel {
success: boolean;
}Download dubbed audio for specific languages. If the dubbing was edited in Dubbing Studio, use the resource render endpoint instead.
/**
* Get dubbed audio/video file for a specific language as MP3 or MP4 stream.
* Note: If edited in Dubbing Studio, use client.dubbing.resource.render() instead.
*
* @param dubbing_id - ID of the dubbing project
* @param language_code - ID of the target language
* @param requestOptions - Optional request configuration
* @returns Streamed audio/video file
* @throws ForbiddenError if not authorized
* @throws NotFoundError if dubbing not found
* @throws UnprocessableEntityError if request fails
* @throws TooEarlyError if dubbing not ready
*/
client.dubbing.audio.get(
dubbing_id: string,
language_code: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;Access and manage transcripts for dubbed content in SRT, WEBVTT, or JSON formats.
/**
* Get transcript for dubbed content in SRT, WEBVTT, or JSON format.
* Note: JSON format not supported for Dubbing Studio projects.
*
* @param dubbing_id - ID of the dubbing project
* @param language_code - ID of the language (target language or source)
* @param request - Format options
* @param requestOptions - Optional request configuration
* @returns Transcript in requested format (string for SRT/WEBVTT, object for JSON)
* @throws ForbiddenError if not authorized
* @throws NotFoundError if dubbing not found
* @throws UnprocessableEntityError if request fails
* @throws TooEarlyError if dubbing not ready
*/
client.dubbing.transcript.getTranscriptForDub(
dubbing_id: string,
language_code: string,
request?: TranscriptGetTranscriptForDubRequest,
requestOptions?: RequestOptions
): HttpResponsePromise<TranscriptGetTranscriptForDubResponse>;
interface TranscriptGetTranscriptForDubRequest {
/** Format type: "srt", "webvtt", or "json" (json not supported for Dubbing Studio) */
formatType?: "srt" | "webvtt" | "json";
}
/**
* Response type varies by format:
* - For "srt" or "webvtt": string with formatted subtitles
* - For "json": DubbingTranscriptResponseModel object
*/
type TranscriptGetTranscriptForDubResponse = string | DubbingTranscriptResponseModel;
interface DubbingTranscriptResponseModel {
/** Transcript text or structured data */
transcript: string | TranscriptSegment[];
}
interface TranscriptSegment {
/** Segment text */
text: string;
/** Start time in seconds */
start: number;
/** End time in seconds */
end: number;
/** Speaker ID */
speaker_id?: number;
}Advanced dubbing project resource management for Dubbing Studio projects. These endpoints require dubbingStudio: true when creating the dubbing job.
/**
* Get complete dubbing resource with all media tracks, segments, and renders.
* Requires studio enabled.
*
* @param dubbing_id - ID of the dubbing project
* @param requestOptions - Optional request configuration
* @returns Complete dubbing resource with tracks, segments, and renders
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.get(
dubbing_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<DubbingResource>;
/**
* Change attribution of segments to a different speaker.
*
* @param dubbing_id - ID of the dubbing project
* @param request - Segment IDs and target speaker
* @param requestOptions - Optional request configuration
* @returns Migration response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.migrateSegments(
dubbing_id: string,
request: BodyMoveSegmentsBetweenSpeakersV1DubbingResourceDubbingIdMigrateSegmentsPost,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentMigrationResponse>;
/**
* Regenerate transcriptions for specified segments.
* Does not automatically regenerate translations or dubs.
*
* @param dubbing_id - ID of the dubbing project
* @param request - List of segment IDs to transcribe
* @param requestOptions - Optional request configuration
* @returns Transcription response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.transcribe(
dubbing_id: string,
request: BodyTranscribesSegmentsV1DubbingResourceDubbingIdTranscribePost,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentTranscriptionResponse>;
/**
* Regenerate translations for specified segments and languages.
* Automatically transcribes missing transcriptions but does not regenerate dubs.
*
* @param dubbing_id - ID of the dubbing project
* @param request - Segments and optional languages to translate
* @param requestOptions - Optional request configuration
* @returns Translation response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.translate(
dubbing_id: string,
request: BodyTranslatesAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdTranslatePost,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentTranslationResponse>;
/**
* Regenerate dubs for specified segments and languages.
* Automatically transcribes and translates missing content.
*
* @param dubbing_id - ID of the dubbing project
* @param request - Segments and optional languages to dub
* @param requestOptions - Optional request configuration
* @returns Dubbing response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.dub(
dubbing_id: string,
request: BodyDubsAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdDubPost,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentDubResponse>;
/**
* Regenerate output media for a language using latest Studio state.
* Asynchronous operation - ensure all segments are dubbed before rendering.
*
* @param dubbing_id - ID of the dubbing project
* @param language - Target language code (e.g., 'es') or 'original' for source track
* @param request - Render configuration
* @param requestOptions - Optional request configuration
* @returns Render response with status and render ID
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.render(
dubbing_id: string,
language: string,
request: BodyRenderAudioOrVideoForTheGivenLanguageV1DubbingResourceDubbingIdRenderLanguagePost,
requestOptions?: RequestOptions
): HttpResponsePromise<DubbingRenderResponseModel>;
interface BodyMoveSegmentsBetweenSpeakersV1DubbingResourceDubbingIdMigrateSegmentsPost {
/** Array of segment IDs to migrate */
segmentIds: string[];
/** ID of target speaker */
speakerId: string;
}
interface BodyTranscribesSegmentsV1DubbingResourceDubbingIdTranscribePost {
/** List of segment IDs to transcribe */
segments: string[];
}
interface BodyTranslatesAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdTranslatePost {
/** List of segment IDs to translate */
segments: string[];
/** Optional: specific languages to translate (empty = all) */
languages?: string[];
}
interface BodyDubsAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdDubPost {
/** List of segment IDs to dub */
segments: string[];
/** Optional: specific languages to dub (empty = all) */
languages?: string[];
}
interface BodyRenderAudioOrVideoForTheGivenLanguageV1DubbingResourceDubbingIdRenderLanguagePost {
/** Render type/format */
renderType: "mp4" | "aac" | "mp3" | "wav" | "aaf" | "tracks_zip" | "clips_zip";
/** Whether to normalize audio volume */
normalizeVolume?: boolean;
}
interface SegmentMigrationResponse {
/** Migration status */
status: string;
}
interface SegmentTranscriptionResponse {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface SegmentTranslationResponse {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface SegmentDubResponse {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface DubbingRenderResponseModel {
/** Operation status */
status: string;
/** Render ID for tracking */
renderId?: string;
}Add and manage languages in dubbing projects.
/**
* Add a language to the dubbing resource
* @param dubbing_id - ID of the dubbing project
* @param request - Language configuration
* @param requestOptions - Optional request configuration
* @returns Language added response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.language.add(
dubbing_id: string,
request?: BodyAddALanguageToTheResourceV1DubbingResourceDubbingIdLanguagePost,
requestOptions?: RequestOptions
): HttpResponsePromise<LanguageAddedResponse>;
interface BodyAddALanguageToTheResourceV1DubbingResourceDubbingIdLanguagePost {
/** Language code to add */
language?: string;
}
interface LanguageAddedResponse {
/** Success status */
success: boolean;
/** Language code that was added */
language: string;
}Update and delete dubbing segments. Note: updating a segment does not automatically regenerate the dub.
/**
* Update a single segment with new text and/or timing.
* Does not automatically regenerate the dub - call resource.dub() after updating.
*
* @param dubbing_id - ID of the dubbing project
* @param segment_id - ID of the segment
* @param language - Language ID
* @param request - Segment update payload
* @param requestOptions - Optional request configuration
* @returns Segment update response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.segment.update(
dubbing_id: string,
segment_id: string,
language: string,
request?: SegmentUpdatePayload,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentUpdateResponse>;
/**
* Delete a single segment from the dubbing project.
*
* @param dubbing_id - ID of the dubbing project
* @param segment_id - ID of the segment to delete
* @param requestOptions - Optional request configuration
* @returns Segment deletion response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.segment.delete(
dubbing_id: string,
segment_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentDeleteResponse>;
interface SegmentUpdatePayload {
/** New start time in seconds */
startTime?: number;
/** New end time in seconds */
endTime?: number;
/** Updated text for the segment */
text?: string;
}
interface SegmentUpdateResponse {
/** Success status */
success: boolean;
/** Updated segment ID */
segment_id: string;
}
interface SegmentDeleteResponse {
/** Success status */
success: boolean;
/** Deleted segment ID */
segment_id: string;
}Create, update, and manage speakers in dubbing projects, including voice selection and discovery.
/**
* Create a new speaker in the dubbing project.
*
* @param dubbing_id - ID of the dubbing project
* @param request - Speaker creation configuration
* @param requestOptions - Optional request configuration
* @returns Speaker creation response with speaker ID
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.speaker.create(
dubbing_id: string,
request?: BodyCreateANewSpeakerV1DubbingResourceDubbingIdSpeakerPost,
requestOptions?: RequestOptions
): HttpResponsePromise<SpeakerCreatedResponse>;
/**
* Update speaker metadata including voice selection and voice settings.
*
* @param dubbing_id - ID of the dubbing project
* @param speaker_id - ID of the speaker
* @param request - Speaker metadata update
* @param requestOptions - Optional request configuration
* @returns Speaker updated response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.speaker.update(
dubbing_id: string,
speaker_id: string,
request?: BodyUpdateMetadataForASpeakerV1DubbingResourceDubbingIdSpeakerSpeakerIdPatch,
requestOptions?: RequestOptions
): HttpResponsePromise<SpeakerUpdatedResponse>;
/**
* Find top 10 similar voices from the voice library for a speaker.
* Returns voice IDs, names, descriptions, and sample audio URLs.
*
* @param dubbing_id - ID of the dubbing project
* @param speaker_id - ID of the speaker
* @param requestOptions - Optional request configuration
* @returns List of 10 similar voices with metadata and sample audio
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.speaker.findSimilarVoices(
dubbing_id: string,
speaker_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<SimilarVoicesForSpeakerResponse>;
/**
* Create a new segment for a specific speaker.
* Does not automatically generate transcripts/translations/audio - creates segment for every available language.
*
* @param dubbing_id - ID of the dubbing project
* @param speaker_id - ID of the speaker
* @param request - Segment creation configuration
* @param requestOptions - Optional request configuration
* @returns Segment creation response
* @throws UnprocessableEntityError if request fails
*/
client.dubbing.resource.speaker.segment.create(
dubbing_id: string,
speaker_id: string,
request: SegmentCreatePayload,
requestOptions?: RequestOptions
): HttpResponsePromise<SegmentCreateResponse>;
interface BodyCreateANewSpeakerV1DubbingResourceDubbingIdSpeakerPost {
/** Name to attribute to speaker */
speakerName?: string;
/** Voice library ID or 'track-clone' | 'clip-clone' */
voiceId?: string;
/** Voice stability [0.0, 1.0] (default: 0.65) */
voiceStability?: number;
/** Voice similarity boost [0.0, 1.0] (default: 1.0) */
voiceSimilarity?: number;
/** Voice style [0.0, 1.0] (default: 1.0) */
voiceStyle?: number;
}
interface BodyUpdateMetadataForASpeakerV1DubbingResourceDubbingIdSpeakerSpeakerIdPatch {
/** Name to attribute to speaker */
speakerName?: string;
/** Voice library ID or 'track-clone' | 'clip-clone' */
voiceId?: string;
/** Voice stability [0.0, 1.0] (default: 0.65) */
voiceStability?: number;
/** Voice similarity boost [0.0, 1.0] (default: 1.0) */
voiceSimilarity?: number;
/** Voice style [0.0, 1.0] (default: 1.0) */
voiceStyle?: number;
/** Languages to apply changes to (empty = all languages) */
languages?: string[];
}
interface SegmentCreatePayload {
/** Start time in seconds (required) */
startTime: number;
/** End time in seconds (required) */
endTime: number;
/** Segment text content */
text?: string;
/** Language-specific translations */
translations?: Record<string, string | undefined>;
}
interface SpeakerCreatedResponse {
/** Success status */
success: boolean;
/** Created speaker ID */
speaker_id: string;
}
interface SpeakerUpdatedResponse {
/** Success status */
success: boolean;
/** Updated speaker ID */
speaker_id: string;
}
interface SegmentCreateResponse {
/** Success status */
success: boolean;
/** Created segment ID */
segment_id: string;
}
interface SimilarVoicesForSpeakerResponse {
/** List of top 10 similar voices */
voices: Array<{
voice_id: string;
name: string;
description?: string;
preview_url?: string;
}>;
}Complete type definitions for dubbing resources and render management.
/**
* Complete dubbing resource with all media and tracks
*/
interface DubbingResource {
/** Resource ID */
id: string;
/** Resource version */
version: number;
/** Source language code */
sourceLanguage: string;
/** Target language codes */
targetLanguages: string[];
/** Input media reference */
input: DubbingMediaReference;
/** Background media reference */
background?: DubbingMediaReference;
/** Foreground media reference */
foreground?: DubbingMediaReference;
/** Speaker tracks indexed by ID */
speakerTracks: Record<string, SpeakerTrack>;
/** Speaker segments indexed by ID */
speakerSegments: Record<string, SpeakerSegment>;
/** Renders indexed by ID */
renders: Record<string, Render>;
}
/**
* Media reference for dubbing assets
*/
interface DubbingMediaReference {
/** Media source path */
src: string;
/** Content type (MIME type) */
contentType: string;
/** Storage bucket name */
bucketName: string;
/** Random path slug for security */
randomPathSlug: string;
/** Duration in seconds */
durationSecs: number;
/** Whether media is audio only */
isAudio: boolean;
/** Full URL to media */
url: string;
}
/**
* Speaker track configuration
*/
interface SpeakerTrack {
/** Track ID */
id: string;
/** Media reference for track */
mediaRef: DubbingMediaReference;
/** Speaker name/identifier */
speakerName: string;
/** Voice IDs per language */
voices: Record<string, string>;
/** Segment IDs in this track */
segments: string[];
}
/**
* Speaker segment with timing and content
*/
interface SpeakerSegment {
/** Segment ID */
id: string;
/** Start time in seconds */
startTime: number;
/** End time in seconds */
endTime: number;
/** Segment text */
text: string;
/** Subtitle frames */
subtitles: SegmentSubtitleFrame[];
/** Dubbed versions per language */
dubs: Record<string, DubbedSegment>;
}
/**
* Subtitle frame for segment
*/
interface SegmentSubtitleFrame {
/** Frame start time */
startTime: number;
/** Frame end time */
endTime: number;
/** Frame text */
text: string;
}
/**
* Dubbed segment in target language
*/
interface DubbedSegment {
/** Dubbed audio reference */
mediaRef: DubbingMediaReference;
/** Dubbed text */
text: string;
/** Start time in dubbed version */
startTime: number;
/** End time in dubbed version */
endTime: number;
}
/**
* Render output configuration
*/
interface Render {
/** Render ID */
id: string;
/** Render version */
version: number;
/** Target language (if applicable) */
language?: string;
/** Render type/format */
type?: RenderType;
/** Output media reference */
mediaRef?: DubbingMediaReference;
/** Render status */
status: RenderStatus;
}
/**
* Render output types
*/
enum RenderType {
MP4 = "mp4",
AAC = "aac",
MP3 = "mp3",
WAV = "wav",
AAF = "aaf",
TRACKS_ZIP = "tracks_zip",
CLIPS_ZIP = "clips_zip",
}
/**
* Render processing status
*/
enum RenderStatus {
COMPLETE = "complete",
PROCESSING = "processing",
FAILED = "failed",
}
/**
* Request for transcribing dubbing resource
*/
interface TranscribeRequestModel {
/** Force re-transcription */
force?: boolean;
}
/**
* Request for translating dubbing resource
*/
interface TranslateRequestModel {
/** Force re-translation */
force?: boolean;
}
/**
* Request for dubbing resource
*/
interface DubRequestModel {
/** Force re-dubbing */
force?: boolean;
/** Voice settings override */
voiceSettings?: VoiceSettings;
}
/**
* Request for rendering dubbing output
*/
interface RenderRequestModel {
/** Render type to generate */
renderType?: RenderType;
/** Force re-render */
force?: boolean;
}
/**
* Response models for dubbing operations
*/
interface TranscribeResponseModel {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface TranslateResponseModel {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface DubResponseModel {
/** Operation status */
status: string;
/** Task ID for tracking */
taskId?: string;
}
interface RenderResponseModel {
/** Operation status */
status: string;
/** Render ID */
renderId?: string;
}
interface MigrateSegmentsResponseModel {
/** Migration status */
status: string;
}
/**
* Dubbing resource response from get operation
*/
interface DubbingResourceResponseModel {
/** The dubbing resource */
resource: DubbingResource;
}import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { readFile, writeFile } from "fs/promises";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Load video file
const videoFile = await readFile("video.mp4");
// Create dubbing job
const dubbing = await client.dubbing.create({
file: new File([videoFile], "video.mp4"),
target_lang: "es", // Spanish
source_lang: "en", // English (optional)
});
console.log("Dubbing ID:", dubbing.dubbing_id);
console.log("Expected duration:", dubbing.expected_duration_sec, "seconds");// Dub into multiple languages at once
const dubbing = await client.dubbing.create({
file: new File([videoFile], "video.mp4"),
target_lang: ["es", "fr", "de", "it"], // Spanish, French, German, Italian
source_lang: "en",
num_speakers: 2, // Specify number of speakers
highest_resolution: true,
});// Dub video from URL instead of uploading
const dubbing = await client.dubbing.create({
source_url: "https://example.com/video.mp4",
target_lang: "ja", // Japanese
watermark: false,
});// Dub only a portion of the video
const dubbing = await client.dubbing.create({
file: new File([videoFile], "video.mp4"),
target_lang: "pt", // Portuguese
start_time: 30, // Start at 30 seconds
end_time: 120, // End at 2 minutes
});// Poll for dubbing completion
async function waitForDubbing(dubbingId: string): Promise<void> {
while (true) {
const metadata = await client.dubbing.get(dubbingId);
console.log("Status:", metadata.status);
if (metadata.status === "dubbed") {
console.log("Dubbing complete!");
console.log("Time dubbed:", metadata.time_dubbed_sec, "seconds");
return;
} else if (metadata.status === "failed") {
throw new Error(`Dubbing failed: ${metadata.error}`);
}
// Wait before polling again
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
await waitForDubbing(dubbing.dubbing_id);// Download dubbed audio for each language
const dubbingInfo = await client.dubbing.get(dubbing.dubbing_id);
for (const lang of dubbingInfo.target_languages) {
const audio = await client.dubbing.audio.get(dubbing.dubbing_id, lang);
// Save to file
const chunks: Uint8Array[] = [];
for await (const chunk of audio) {
chunks.push(chunk);
}
const buffer = Buffer.concat(chunks);
await writeFile(`dubbed_${lang}.mp4`, buffer);
console.log(`Downloaded ${lang} dubbing`);
}// Get transcript for source language
const sourceTranscript = await client.dubbing.transcript.getTranscriptForDub(
dubbing.dubbing_id,
dubbingInfo.source_language
);
// Get transcript for target language
const targetTranscript = await client.dubbing.transcript.getTranscriptForDub(
dubbing.dubbing_id,
"es"
);
console.log("Original:", sourceTranscript.transcript);
console.log("Spanish:", targetTranscript.transcript);// Get transcript as SRT subtitle file
const subtitles = await client.dubbing.transcript.getTranscriptForDub(
dubbing.dubbing_id,
"es",
{ format_type: "srt" }
);
await writeFile("subtitles_es.srt", subtitles.transcript);// List all dubbing projects
const projects = await client.dubbing.list({
pageSize: 50,
dubbingStatus: "dubbed",
filterByCreator: "personal",
orderBy: "created_at",
orderDirection: "DESCENDING",
});
for (const project of projects.dubbings) {
console.log(`${project.dubbing_id}: ${project.name || "Unnamed"}`);
console.log(` Status: ${project.status}`);
console.log(` Languages: ${project.target_languages.join(", ")}`);
}
// Paginate through results
let cursor = projects.next_cursor;
while (cursor && projects.has_more) {
const nextPage = await client.dubbing.list({
cursor,
pageSize: 50,
});
// Process next page...
cursor = nextPage.next_cursor;
}// Delete a dubbing project
await client.dubbing.delete(dubbing.dubbing_id);
console.log("Dubbing project deleted");async function dubVideo(
videoPath: string,
targetLanguages: string[]
): Promise<void> {
// 1. Upload and create dubbing job
const videoFile = await readFile(videoPath);
const dubbing = await client.dubbing.create({
file: new File([videoFile], videoPath),
target_lang: targetLanguages,
source_lang: "en",
highest_resolution: true,
});
console.log("Dubbing job created:", dubbing.dubbing_id);
// 2. Wait for completion
await waitForDubbing(dubbing.dubbing_id);
// 3. Download all dubbed versions
const info = await client.dubbing.get(dubbing.dubbing_id);
for (const lang of info.target_languages) {
// Download audio
const audio = await client.dubbing.audio.get(dubbing.dubbing_id, lang);
const chunks = [];
for await (const chunk of audio) {
chunks.push(chunk);
}
await writeFile(`output_${lang}.mp4`, Buffer.concat(chunks));
// Download subtitles
const srt = await client.dubbing.transcript.getTranscriptForDub(
dubbing.dubbing_id,
lang,
{ format_type: "srt" }
);
await writeFile(`subtitles_${lang}.srt`, srt.transcript);
console.log(`Saved ${lang} dubbing and subtitles`);
}
}
await dubVideo("presentation.mp4", ["es", "fr", "de"]);