Translate a remote video
Validates a remote video and starts an asynchronous translation request.
Optional config.source_srt / config.target_srts supply subtitles and
config.speaker_voices assigns voices to speakers (see VideoTranslateConfig).
When webhook_url is supplied, the service sends one JSON POST after the
request reaches completed or failed. The event type is
video_translate.completed or video_translate.failed; the request body uses
{id, type, created_at, data} and data mirrors the public request response
without webhook_url. Successful events include freshly signed video, audio and
SRT URLs. Receivers should deduplicate on X-Chamelaion-Delivery. Transport
failures, HTTP 429 and HTTP 5xx are retried up to three times with the same
delivery ID; redirects and other non-2xx responses are not accepted.
Validation happens in two phases:
- Synchronous (HTTP 400, no request is created): request shape, config types,
SRT size, UTF-8 encoding and syntax (optional BOM stripped, CRLF/CR normalized
to LF), cue limit, language consistency,
target_srtskeys must be listed intarget_languages, speaker ID syntax, and voice availability (everyspeaker_voicesvalue must be avoice_idreturned byGET /v1/video-translate/voices). - After the video is processed, before translation starts: SRT timing against
the video duration (+1.2 s tolerance), source/target cue count and speaker
compatibility, the detected source language against
source_srt.language, andspeaker_voiceskeys against the speakers in the source subtitles (or, without any SRT, the speakers already stored for the media). Failures mark the requestfailedwith a descriptiveerror_message; no translation is started.
Limits: JSON body 8 MiB; each SRT 1 MiB; all SRTs 5 MiB; 5000 cues per SRT;
32 speaker_voices entries; config keys other than source_srt, target_srts
and speaker_voices 64 KiB in total; normalized config 6 MiB (measured without
HTML escaping). Duplicate JSON keys anywhere in the body and NUL characters in
config are rejected.
Translate a remote video
import Chamelaion from 'chamelaion';
const client = new Chamelaion({
bearerToken: process.env['CHAMELAION_BEARER_TOKEN'], // This is the default and can be omitted
});
const response = await client.videoTranslate.generate({
inputs: [
{ type: 'video', url: 'https://storage.googleapis.com/chamelaion-test-media/video.mp4' },
],
target_languages: ['de', 'fr'],
config: {
source_srt: {
file_name: 'interview.srt',
content:
'1\n00:00:00,000 --> 00:00:02,500\nSpeaker 0: Welcome back.\n\n2\n00:00:02,600 --> 00:00:05,000\nSpeaker 1: Thanks for having me.\n',
},
target_srts: {
de: {
content:
'1\n00:00:00,000 --> 00:00:02,500\nSpeaker 0: Willkommen zurück.\n\n2\n00:00:02,600 --> 00:00:05,000\nSpeaker 1: Danke für die Einladung.\n',
},
},
speaker_voices: { '0': '21m00Tcm4TlvDq8ikWAM', '1': 'AZnzlk1XvdvUeBnXmlld' },
},
model: 'expressive',
reference_id: 'customer-job-42',
source_language: 'en',
webhook_url: 'https://hooks.example.com/chamelaion/video-translate',
});
console.log(response.request_id);{
"status": "success",
"request_id": "4c98dd00-a982-47d9-a8d6-e1f0b35a8944"
}{
"error": "target_languages must contain at least one language"
}{
"error": "duplicate target language \"de\""
}{
"error": "input must be a video file"
}{
"error": "config must be a valid JSON object"
}{
"error": "config.source_srt is not a valid SRT file: Line 2: invalid time format, 00:00:01 --> 00:00:02, expecting in '00:00:04,139 --> 00:00:04,799' format"
}{
"error": "config.target_srts.fr: language \"fr\" is not listed in target_languages"
}{
"error": "source_srt must be supplied either in config or as a multipart file, not both"
}{
"error": "config.speaker_voices key \"speaker-1\" must be a non-negative integer speaker ID such as \"1\""
}{
"error": "speaker_voices references unknown or unavailable voice IDs: \"missing-voice\""
}{
"error": "missing authorization header"
}{
"error": "invalid authorization format"
}{
"error": "missing token"
}{
"error": "invalid token"
}{
"error": "unauthorized"
}{
"error": "request body exceeds the 8 MiB limit"
}{
"error": "rate limit exceeded"
}{
"error": "internal error"
}Returns Examples
{
"status": "success",
"request_id": "4c98dd00-a982-47d9-a8d6-e1f0b35a8944"
}{
"error": "target_languages must contain at least one language"
}{
"error": "duplicate target language \"de\""
}{
"error": "input must be a video file"
}{
"error": "config must be a valid JSON object"
}{
"error": "config.source_srt is not a valid SRT file: Line 2: invalid time format, 00:00:01 --> 00:00:02, expecting in '00:00:04,139 --> 00:00:04,799' format"
}{
"error": "config.target_srts.fr: language \"fr\" is not listed in target_languages"
}{
"error": "source_srt must be supplied either in config or as a multipart file, not both"
}{
"error": "config.speaker_voices key \"speaker-1\" must be a non-negative integer speaker ID such as \"1\""
}{
"error": "speaker_voices references unknown or unavailable voice IDs: \"missing-voice\""
}{
"error": "missing authorization header"
}{
"error": "invalid authorization format"
}{
"error": "missing token"
}{
"error": "invalid token"
}{
"error": "unauthorized"
}{
"error": "request body exceeds the 8 MiB limit"
}{
"error": "rate limit exceeded"
}{
"error": "internal error"
}