JavaScript SDK
Official JavaScript/TypeScript client for the Subformer API
The official JavaScript/TypeScript SDK for Subformer provides a simple interface for video dubbing, voice cloning, and text-to-speech with full TypeScript support.
Installation
npm install subformer
# or
yarn add subformer
# or
pnpm add subformer
# or
bun add subformerQuick Start
import Subformer from 'subformer';
// Initialize the client
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// Dub a YouTube video to Spanish
const job = await client.dub({
source: 'youtube',
url: 'https://youtube.com/watch?v=VIDEO_ID',
language: 'es-ES'
});
// Wait for completion
const result = await client.waitForJob(job.id);
console.log(`Dubbed video: ${result.output.videoUrl}`);Features
- Video Dubbing - Translate videos from YouTube, TikTok, Instagram, Facebook, X, and direct URLs to 50+ languages
- Voice Cloning - Transform audio to match target voices
- Text-to-Speech - Generate natural-sounding speech from text
- Voice Library - Save and manage custom voices
- TypeScript Support - Full type definitions included
- Promise-based - Modern async/await API
Video Dubbing
Dub videos from various platforms:
import Subformer from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// YouTube
const job = await client.dub({
source: 'youtube',
url: 'https://youtube.com/watch?v=...',
language: 'es-ES'
});
// TikTok
const job = await client.dub({
source: 'tiktok',
url: 'https://tiktok.com/@user/video/...',
language: 'fr-FR'
});
// Instagram
const job = await client.dub({
source: 'instagram',
url: 'https://instagram.com/reel/...',
language: 'de-DE'
});
// Direct URL
const job = await client.dub({
source: 'url',
url: 'https://example.com/video.mp4',
language: 'ja-JP'
});
// Wait for completion
const result = await client.waitForJob(job.id);
console.log(result.output);Voice Cloning
Clone voices using preset or custom voice samples:
import Subformer from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// Using a preset voice
const job = await client.cloneVoice({
sourceAudioUrl: 'https://example.com/speech.mp3',
targetVoice: {
mode: 'preset',
presetVoiceId: 'morgan-freeman'
}
});
// Using an uploaded voice sample
const job = await client.cloneVoice({
sourceAudioUrl: 'https://example.com/speech.mp3',
targetVoice: {
mode: 'upload',
targetAudioUrl: 'https://example.com/my-voice.mp3'
}
});
const result = await client.waitForJob(job.id);
console.log(result.output.audioUrl);Text-to-Speech
Generate speech from text:
import Subformer from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// Using a preset voice
const job = await client.synthesizeVoice({
text: 'Hello, welcome to Subformer!',
targetVoice: {
mode: 'preset',
presetVoiceId: 'professional-narrator'
}
});
// Using a custom voice
const job = await client.synthesizeVoice({
text: 'This is my cloned voice speaking.',
targetVoice: {
mode: 'upload',
targetAudioUrl: 'https://example.com/my-voice.mp3'
}
});
const result = await client.waitForJob(job.id);
console.log(result.output.audioUrl);Voice Library
Manage your saved voices:
import Subformer from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// List all voices
const voices = await client.listVoices();
for (const voice of voices) {
console.log(`${voice.name}: ${voice.id}`);
}
// Create a new voice
const voice = await client.createVoice({
name: 'My Custom Voice',
audioUrl: 'https://example.com/voice-sample.mp3'
});
// Update a voice
await client.updateVoice(voice.id, { name: 'Updated Voice Name' });
// Delete a voice
await client.deleteVoice(voice.id);Job Management
import Subformer from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
// List recent jobs
const jobs = await client.listJobs({ limit: 10 });
// Get a specific job
const job = await client.getJob('job_id_here');
// Wait for a job with custom timeout
const result = await client.waitForJob(job.id, {
timeout: 300000, // 5 minutes
pollInterval: 2000 // Check every 2 seconds
});Error Handling
import Subformer, { SubformerError, AuthenticationError, RateLimitError } from 'subformer';
const client = new Subformer({ apiKey: 'sk_subformer_...' });
try {
const job = await client.dub({
source: 'youtube',
url: 'https://youtube.com/watch?v=...',
language: 'es-ES'
});
const result = await client.waitForJob(job.id);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded, please wait');
} else if (error instanceof SubformerError) {
console.error(`API error: ${error.message}`);
}
}Configuration
import Subformer from 'subformer';
const client = new Subformer({
apiKey: 'sk_subformer_...',
baseUrl: 'https://api.subformer.com/v1', // Optional: custom base URL
timeout: 30000, // Optional: request timeout in milliseconds
});TypeScript Types
The SDK includes full TypeScript definitions:
import Subformer, {
DubJob,
VoiceCloneJob,
SynthesizeJob,
Voice,
JobStatus,
SupportedLanguage
} from 'subformer';
// Types are automatically inferred
const job: DubJob = await client.dub({ ... });
const voices: Voice[] = await client.listVoices();