Doubler le projet
curl --request POST \
--url https://api.voicecheap.ai/v1/projects/{projectId}/dub \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"targetLanguage": "<string>",
"translatedSrt": "<string>",
"webhookUrl": "<string>",
"keepBackgroundMusic": true,
"keepOriginalVoice": true,
"originalVoiceVolume": 123,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceIsolatorOption": "<string>",
"subtitles": true,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": true,
"voiceCloningSettings": {},
"translationTimeSkips": [
{}
]
}
'import requests
url = "https://api.voicecheap.ai/v1/projects/{projectId}/dub"
payload = {
"targetLanguage": "<string>",
"translatedSrt": "<string>",
"webhookUrl": "<string>",
"keepBackgroundMusic": True,
"keepOriginalVoice": True,
"originalVoiceVolume": 123,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceIsolatorOption": "<string>",
"subtitles": True,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": True,
"voiceCloningSettings": {},
"translationTimeSkips": [{}]
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
targetLanguage: '<string>',
translatedSrt: '<string>',
webhookUrl: '<string>',
keepBackgroundMusic: true,
keepOriginalVoice: true,
originalVoiceVolume: 123,
voiceMode: '<string>',
voiceId: '<string>',
voiceIsolatorOption: '<string>',
subtitles: true,
subtitlesSource: '<string>',
lipSyncMode: '<string>',
activeSpeakerDetectionEnabled: true,
voiceCloningSettings: {},
translationTimeSkips: [{}]
})
};
fetch('https://api.voicecheap.ai/v1/projects/{projectId}/dub', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.voicecheap.ai/v1/projects/{projectId}/dub",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'targetLanguage' => '<string>',
'translatedSrt' => '<string>',
'webhookUrl' => '<string>',
'keepBackgroundMusic' => true,
'keepOriginalVoice' => true,
'originalVoiceVolume' => 123,
'voiceMode' => '<string>',
'voiceId' => '<string>',
'voiceIsolatorOption' => '<string>',
'subtitles' => true,
'subtitlesSource' => '<string>',
'lipSyncMode' => '<string>',
'activeSpeakerDetectionEnabled' => true,
'voiceCloningSettings' => [
],
'translationTimeSkips' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.voicecheap.ai/v1/projects/{projectId}/dub"
payload := strings.NewReader("{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.voicecheap.ai/v1/projects/{projectId}/dub")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.voicecheap.ai/v1/projects/{projectId}/dub")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"projectId": "<string>",
"workId": "<string>",
"estimatedDuration": 123
}Traduction et doublage
Doubler le projet
Doubler un projet déjà transcrit à partir de votre propre SRT traduit
Doubler le projet
curl --request POST \
--url https://api.voicecheap.ai/v1/projects/{projectId}/dub \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"targetLanguage": "<string>",
"translatedSrt": "<string>",
"webhookUrl": "<string>",
"keepBackgroundMusic": true,
"keepOriginalVoice": true,
"originalVoiceVolume": 123,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceIsolatorOption": "<string>",
"subtitles": true,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": true,
"voiceCloningSettings": {},
"translationTimeSkips": [
{}
]
}
'import requests
url = "https://api.voicecheap.ai/v1/projects/{projectId}/dub"
payload = {
"targetLanguage": "<string>",
"translatedSrt": "<string>",
"webhookUrl": "<string>",
"keepBackgroundMusic": True,
"keepOriginalVoice": True,
"originalVoiceVolume": 123,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceIsolatorOption": "<string>",
"subtitles": True,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": True,
"voiceCloningSettings": {},
"translationTimeSkips": [{}]
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
targetLanguage: '<string>',
translatedSrt: '<string>',
webhookUrl: '<string>',
keepBackgroundMusic: true,
keepOriginalVoice: true,
originalVoiceVolume: 123,
voiceMode: '<string>',
voiceId: '<string>',
voiceIsolatorOption: '<string>',
subtitles: true,
subtitlesSource: '<string>',
lipSyncMode: '<string>',
activeSpeakerDetectionEnabled: true,
voiceCloningSettings: {},
translationTimeSkips: [{}]
})
};
fetch('https://api.voicecheap.ai/v1/projects/{projectId}/dub', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.voicecheap.ai/v1/projects/{projectId}/dub",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'targetLanguage' => '<string>',
'translatedSrt' => '<string>',
'webhookUrl' => '<string>',
'keepBackgroundMusic' => true,
'keepOriginalVoice' => true,
'originalVoiceVolume' => 123,
'voiceMode' => '<string>',
'voiceId' => '<string>',
'voiceIsolatorOption' => '<string>',
'subtitles' => true,
'subtitlesSource' => '<string>',
'lipSyncMode' => '<string>',
'activeSpeakerDetectionEnabled' => true,
'voiceCloningSettings' => [
],
'translationTimeSkips' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.voicecheap.ai/v1/projects/{projectId}/dub"
payload := strings.NewReader("{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.voicecheap.ai/v1/projects/{projectId}/dub")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.voicecheap.ai/v1/projects/{projectId}/dub")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"targetLanguage\": \"<string>\",\n \"translatedSrt\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"voiceCloningSettings\": {},\n \"translationTimeSkips\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"projectId": "<string>",
"workId": "<string>",
"estimatedDuration": 123
}Doubler le projet
Générez les voix et mixez la sortie d’un projet existant à partir d’un SRT traduit que vous fournissez. VoiceCheap ne traduit rien sur ce point de terminaison : pas de moteur de traduction, pas de reformulation SmartSync, pas de glossaire. Chaque réplique est lue telle quelle sur le segment correspondant de la transcription du projet, puis mixée avec l’arrière-plan d’origine, les sous-titres et la synchronisation labiale facultative, exactement comme une traduction classique. Utilisez-le lorsque la traduction est produite ailleurs (un traducteur humain, vos propres outils, un flux d’automatisation) et que vous n’avez besoin de VoiceCheap que pour générer les voix. L’exécution est asynchrone : interrogez Obtenir le statut de la traduction ou écoutez les Webhooks.Prérequis
- Le projet doit exister et sa transcription doit être terminée : créez-le avec Créer un projet (transcription seule) ou Démarrer la traduction, puis attendez
transcriptionStatus: "success". - Votre SRT doit couvrir la transcription du projet : chaque segment a besoin d’au moins une réplique, et chaque réplique doit tomber sur un segment. Exportez la transcription avec Exporter la transcription du projet et traduisez-la réplique par réplique pour conserver les codes temporels.
- La requête est facturée comme une traduction du même média, avec le même contrôle de crédits. Les modes de synchronisation labiale ajoutent leurs crédits supplémentaires habituels.
Limite de concurrence
La création de projets, la traduction et le doublage vérifient tous la limite de traductions actives de votre compte (10 au maximum, parfois moins). Seules les traductions ou les opérations de doublage en cours occupent des places ; les projets limités à la transcription n’en occupent pas. Lorsque cette limite est atteinte, l’API renvoieCONCURRENT_TRANSLATION_LIMIT_REACHED (HTTP 429). La limite appliquée figure dans details.limit.
Une seconde exécution pour le même projet et la même langue cible est aussi refusée tant qu’une autre est en cours (TRANSLATION_ALREADY_IN_PROGRESS, HTTP 409).
Requête
Ce point de terminaison accepte un corps JSON (Content-Type: application/json). Les options booléennes et numériques sont envoyées comme valeurs JSON, pas comme des chaînes.
En-têtes
string
requis
Votre clé API VoiceCheap. Obtenez-en une sur app.voicecheap.ai/page-api.
Paramètres de chemin
string
requis
L’identifiant du projet renvoyé par Créer un projet ou Démarrer la traduction.
Paramètres du corps de la requête
string
requis
La langue de
translatedSrt, en minuscules, dans la même liste que Démarrer la traduction. Si le projet n’a pas encore de travail pour cette langue, un travail est créé et la langue est ajoutée au projet.string
requis
Le contenu SRT final dans la langue cible (numéro de réplique, ligne de temps, texte). Maximum 1 000 000 caractères. Les répliques sont associées aux segments de transcription par les horodatages : une réplique qui commence à moins de 50 ms du début d’un segment lui est attribuée, sinon au segment qu’elle chevauche le plus. Plusieurs répliques sur un même segment sont jointes par une espace. Le minutage, le locuteur et l’ordre de chaque segment lu viennent toujours de la transcription du projet ; vos codes temporels servent uniquement à l’association.
string
Un point de terminaison https qui reçoit désormais les événements webhook de ce projet et remplace le point de terminaison configuré sur le compte.Par défaut : Le point de terminaison déjà enregistré sur le projet, puis le point de terminaison webhook du compte.
boolean
Conserver l’audio d’arrière-plan d’origine (musique, ambiance) sous les voix générées.Par défaut :
trueboolean
Conserver la voix d’origine discrètement sous la voix générée.Par défaut :
falsenumber
Volume de la voix d’origine de
1 à 70 lorsque keepOriginalVoice est activé.Par défaut : 30string
Stratégie vocale :
cloning (cloner les voix des intervenants du projet) ou custom (utiliser une voix du catalogue ou votre voix personnalisée enregistrée).Par défaut : cloningstring
Requis lorsque
voiceMode est custom. Utilisez un identifiant de dubbing_voices_list : une voix du catalogue ou une voix personnalisée
enregistrée par le compte authentifié. La facturation en équipe ne donne pas accès aux voix enregistrées des autres membres.string
Mode d’isolation de la voix lorsque
keepBackgroundMusic est activé : studio ou realistic.Par défaut : studioboolean
Incruster les sous-titres dans la vidéo de sortie. Nécessite un projet vidéo.Par défaut :
falsestring
Texte des sous-titres lorsque
subtitles est activé : translated (votre SRT) ou original (la transcription source).Par défaut : translatedstring
Lancer la synchronisation labiale une fois le doublage prêt :
standard, pro ou studio. Les règles de forfait, de durée et de crédits sont les mêmes que sur Démarrer la traduction. Nécessite un projet vidéo.Par défaut : omettez le champ pour ignorer la synchronisation labiale.boolean
Activer la détection du locuteur actif pour l’exécution de synchronisation labiale demandée.Par défaut :
falseobject
Réglage fin du clonage de voix, sous forme d’objet JSON avec
stability et similarity entre 0 et 1. Uniquement avec voiceMode: "cloning". Voir Démarrer la traduction pour le rôle de chaque valeur.array
Plages du temps source à laisser dans la langue d’origine, sous la forme
[{ "startTime": 10.2, "endTime": 12.8 }]. Nécessite un projet vidéo et keepBackgroundMusic: true, ne peut pas être combiné avec keepOriginalVoice et ne peut pas chevaucher des segments de transcription.Réponse
boolean
requis
Toujours
true pour les requêtes réussies.string
requis
Une confirmation lisible.
string
requis
Le projet en cours de doublage.
string
requis
Le travail de traduction utilisé pour
targetLanguage. Il correspond à workId dans les points de terminaison de statut, de détails et de transcription.number
requis
Estimation approximative du traitement en minutes : cinq minutes de traitement par minute entamée du média source.
Response
{
"success": true,
"message": "Dubbing started successfully from the provided translation. Use the status endpoint to track progress.",
"projectId": "project_123",
"workId": "work_456",
"estimatedDuration": 10
}
Suivre l’exécution
Le projet passe au fluxtranslation dès que le doublage démarre, donc Obtenir le statut de la traduction suit la nouvelle exécution : status passe de processing à success (avec translatedVideoUrl et translatedAudioUrl) ou à failed (avec error). Les webhooks project.translation.completed et project.translation.failed sont envoyés avec le même targetLanguage. Dans Obtenir les détails du projet, la version traduite indique settings.dubbingMode: "dub-only" et settings.smartSync: false.
Les échecs d’alignement apparaissent après l’acceptation de la requête POST. Le point de terminaison de statut renvoie status: "failed" avec error.code et error.message ; le webhook project.translation.failed porte le même code et le même message. TRANSLATED_SRT_UNMATCHED_CUES indique dans le message les numéros de répliques sans correspondance, et TRANSLATED_SRT_MISSING_SEGMENTS les index des segments sans réplique. Ces réponses asynchrones ne contiennent pas de champ details structuré. Corrigez le SRT et rappelez le point de terminaison : la version en échec reste dans l’historique et une nouvelle est créée.
Vérifier le rythme
Exportez la transcription traduite en JSON avec Exporter la transcription du projet. Chaque segment portefinalSpeedFactor, le rapport entre la voix générée et la fenêtre du segment. Raccourcissez les répliques qui dépassent environ 1.3, puis relancez le doublage avec le SRT révisé.
Exemple de flux
Une automatisation typique (par exemple un scénario n8n ou Make) enchaîne les points de terminaison comme suit :POST /v1/projectsavec le média,targetLanguageet uneoriginalLanguageexplicite (transcription seule).- Interrogez
GET /v1/translate/{projectId}/statusjusqu’à ce quetranscriptionStatusvaillesuccess, ou attendez le webhookproject.created. POST /v1/projects/{projectId}/transcriptavec{ "source": "original", "outputFormat": "srt" }et traduisez les répliques en conservant la numérotation et les codes temporels.POST /v1/projects/{projectId}/dubavec le SRT traduit.- Interrogez le point de terminaison de statut jusqu’à ce que
statusvaillesuccess, ou attendezproject.translation.completed. - Téléchargez
translatedVideoUrl(oulipSync.videoUrlsi une synchronisation labiale a été demandée). DELETE /v1/translate/{projectId}une fois les sorties stockées de votre côté.
curl -X POST "https://api.voicecheap.ai/v1/projects/project_123/dub" \
-H "x-api-key: vc_your-api-key" \
-H "Content-Type: application/json" \
-d '{
"targetLanguage": "english",
"translatedSrt": "1\n00:00:00,000 --> 00:00:02,400\nWelcome to this lesson.\n\n2\n00:00:02,400 --> 00:00:05,100\nToday we talk about fractions.",
"keepBackgroundMusic": true,
"subtitles": true,
"subtitlesSource": "translated"
}'
interface DubProjectResponse {
success: boolean;
message: string;
projectId: string;
workId: string;
estimatedDuration: number;
}
const API_BASE_URL = 'https://api.voicecheap.ai/v1';
const headers = { 'x-api-key': 'vc_your-api-key', 'Content-Type': 'application/json' };
async function waitForStatus(projectId: string, isReady: (status: any) => boolean): Promise<any> {
while (true) {
const status = await fetch(`${API_BASE_URL}/translate/${projectId}/status`, { headers }).then((response) => response.json());
if (status.status === 'failed') throw new Error(`${status.error?.code}: ${status.error?.message}`);
if (isReady(status)) return status;
await new Promise((resolve) => setTimeout(resolve, 15_000));
}
}
async function dubExistingProject(projectId: string, translatedSrt: string): Promise<string> {
// 1. The project was created earlier with POST /v1/projects; wait for its transcript.
await waitForStatus(projectId, (status) => status.transcriptionStatus === 'success');
// 2. Send the translation you produced from the exported transcript.
const dubResponse = await fetch(`${API_BASE_URL}/projects/${projectId}/dub`, {
method: 'POST',
headers,
body: JSON.stringify({ targetLanguage: 'english', translatedSrt, keepBackgroundMusic: true }),
});
if (!dubResponse.ok) {
const error = await dubResponse.json();
throw new Error(`${error.code}: ${error.message}`);
}
const { workId } = (await dubResponse.json()) as DubProjectResponse;
console.log('Dubbing started on work', workId);
// 3. Wait for the dubbed output.
const completed = await waitForStatus(projectId, (status) => status.status === 'success');
return completed.translatedVideoUrl as string;
}
import time
import requests
API_BASE_URL = 'https://api.voicecheap.ai/v1'
HEADERS = {'x-api-key': 'vc_your-api-key'}
def wait_for_status(project_id, is_ready):
while True:
status = requests.get(f'{API_BASE_URL}/translate/{project_id}/status', headers=HEADERS).json()
if status['status'] == 'failed':
raise RuntimeError(f"{status['error']['code']}: {status['error']['message']}")
if is_ready(status):
return status
time.sleep(15)
def dub_existing_project(project_id, translated_srt):
wait_for_status(project_id, lambda status: status['transcriptionStatus'] == 'success')
response = requests.post(
f'{API_BASE_URL}/projects/{project_id}/dub',
headers=HEADERS,
json={'targetLanguage': 'english', 'translatedSrt': translated_srt, 'keepBackgroundMusic': True},
)
response.raise_for_status()
print('Dubbing started on work', response.json()['workId'])
completed = wait_for_status(project_id, lambda status: status['status'] == 'success')
return completed['translatedVideoUrl']
Erreurs
| Statut | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Un champ du corps est absent ou invalide (details liste chaque champ) |
| 400 | INVALID_TRANSLATED_SRT | translatedSrt ne contient pas de répliques SRT valides |
| 400 | INVALID_BOOLEAN_VALUE | Une option booléenne n’a pas été envoyée comme booléen JSON |
| 400 | INVALID_NUMBER_VALUE | Une option numérique n’a pas été envoyée comme nombre JSON |
| 400 | DURATION_DETECTION_FAILED | La durée média enregistrée du projet n’est pas disponible |
| 400 | VOICE_ID_REQUIRED | Le mode voix personnalisées a été sélectionné sans ID de voix |
| 400 | VOICE_ID_NOT_ALLOWED_WITH_CLONING | Un ID de voix a été combiné avec le clonage vocal |
| 400 | VOICE_CLONING_SETTINGS_NOT_ALLOWED | Les paramètres de clonage ont été combinés avec le mode voix personnalisées |
| 400 | TRANSLATION_TIME_SKIP_CONFLICT | Les sauts temporels sont en conflit avec une autre option audio |
| 400 | TRANSLATION_TIME_SKIP_REQUIRES_BACKGROUND | Les sauts temporels nécessitent un audio d’arrière-plan |
| 400 | TRANSLATION_TIME_SKIP_OUT_OF_RANGE | Un saut temporel dépasse la durée du média |
| 400 | SUBTITLES_NOT_AVAILABLE_FOR_AUDIO | Des sous-titres incrustés ont été demandés pour une entrée audio |
| 400 | LIPSYNC_NOT_AVAILABLE_FOR_AUDIO | Une synchronisation labiale a été demandée pour une entrée audio |
| 400 | TRANSLATION_TIME_SKIP_NOT_AVAILABLE_FOR_AUDIO | Des sauts temporels ont été demandés pour une entrée audio |
| 400 | LIPSYNC_VIDEO_TOO_LONG | Une synchronisation labiale a été demandée pour un média plus long que la durée prise en charge |
| 401 | MISSING_API_KEY | La clé API est requise |
| 401 | INVALID_API_KEY_FORMAT | La clé API doit commencer par vc_ |
| 401 | INVALID_API_KEY | La clé API fournie est invalide |
| 403 | SUBSCRIPTION_REQUIRED | L’accès à l’API nécessite un forfait Starter ou supérieur |
| 403 | FORBIDDEN | Vous n’avez pas l’autorisation d’accéder au projet |
| 403 | INSUFFICIENT_CREDITS | Crédits insuffisants pour doubler ce projet |
| 403 | CUSTOM_VOICE_ACCESS_DENIED | La voix sélectionnée ne figure pas dans le catalogue et n’est pas une voix personnalisée enregistrée par le compte authentifié. |
| 403 | LIPSYNC_MODE_ACCESS_DENIED | Le mode de synchronisation labiale premium n’est pas disponible sur le forfait actuel |
| 404 | PROJECT_NOT_FOUND | Le projet n’existe pas |
| 409 | DUB_ONLY_REQUIRES_TRANSCRIPTION | La transcription du projet est encore en cours de traitement ou a échoué |
| 409 | TRANSLATION_ALREADY_IN_PROGRESS | Un doublage est déjà en cours pour cette langue sur le projet |
| 429 | RATE_LIMIT_EXCEEDED | Trop de requêtes (limite : 10 requêtes par minute) |
| 429 | CONCURRENT_TRANSLATION_LIMIT_REACHED | Limite de traductions simultanées du compte atteinte ; voir details.limit |
| 500 | INTERNAL_ERROR | Erreur serveur inattendue |
TRANSLATED_SRT_UNMATCHED_CUES, TRANSLATED_SRT_MISSING_SEGMENTS) sont renvoyés par le point de terminaison de statut et le webhook d’échec, pas par cette requête.Cette page vous a-t-elle été utile ?

