Doppiaggio del progetto
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
}Traduzione e doppiaggio
Doppiaggio del progetto
Doppia un progetto già trascritto a partire dal tuo SRT tradotto
Doppiaggio del progetto
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
}Doppiaggio del progetto
Genera le voci e mixa l’output di un progetto esistente a partire da un SRT tradotto che fornisci tu. VoiceCheap non traduce nulla su questo endpoint: niente motore di traduzione, niente riformulazione SmartSync, niente glossario. Ogni cue viene letto così com’è sul segmento corrispondente della trascrizione del progetto, poi mixato con lo sfondo originale, i sottotitoli e la sincronizzazione labiale facoltativa, esattamente come una traduzione normale. Usalo quando la traduzione è prodotta altrove (un traduttore umano, i tuoi strumenti, un flusso di automazione) e ti serve VoiceCheap solo per generare le voci. L’esecuzione è asincrona: interroga Ottieni lo stato della traduzione oppure ascolta i Webhook.Prerequisiti
- Il progetto deve esistere e la sua trascrizione deve essere completa: crealo con Crea progetto (solo trascrizione) o Avvia traduzione, e attendi
transcriptionStatus: "success". - Il tuo SRT deve coprire la trascrizione del progetto: ogni segmento ha bisogno di almeno un cue e ogni cue deve cadere su un segmento. Esporta la trascrizione con Esporta trascrizione del progetto e traducila cue per cue per mantenere i timecode.
- La richiesta viene addebitata come una traduzione dello stesso media, con lo stesso controllo dei crediti. Le modalità di sincronizzazione labiale aggiungono i soliti crediti extra.
Limite di concorrenza
La creazione dei progetti, la traduzione e il doppiaggio verificano tutti il limite di traduzioni attive dell’account (al massimo 10, eventualmente meno). Solo le traduzioni o i doppiaggi in corso occupano posti; i progetti di sola trascrizione no. Al raggiungimento del limite, l’API restituisceCONCURRENT_TRANSLATION_LIMIT_REACHED (HTTP 429). Il limite applicato è indicato in details.limit.
Una seconda esecuzione per lo stesso progetto e la stessa lingua di destinazione viene rifiutata finché un’altra è in corso (TRANSLATION_ALREADY_IN_PROGRESS, HTTP 409).
Richiesta
Questo endpoint accetta un corpo JSON (Content-Type: application/json). Le opzioni booleane e numeriche vanno inviate come valori JSON, non come stringhe.
Intestazioni
string
obbligatorio
La tua chiave API VoiceCheap. Ottienine una da app.voicecheap.ai/page-api.
Parametri del percorso
string
obbligatorio
L’identificatore del progetto restituito da Crea progetto o Avvia traduzione.
Parametri del corpo
string
obbligatorio
La lingua di
translatedSrt, in minuscolo, dallo stesso elenco di Avvia traduzione. Se il progetto non ha ancora un lavoro per questa lingua, ne viene creato uno e la lingua viene aggiunta al progetto.string
obbligatorio
Il contenuto SRT finale nella lingua di destinazione (numero del cue, riga dei tempi, testo). Massimo 1.000.000 di caratteri. I cue vengono abbinati ai segmenti della trascrizione tramite i timestamp: un cue che inizia entro 50 ms dall’inizio di un segmento viene assegnato a quel segmento, altrimenti al segmento con cui si sovrappone di più. Più cue sullo stesso segmento vengono uniti con uno spazio. Tempo, parlante e ordine di ogni segmento letto provengono sempre dalla trascrizione del progetto; i tuoi timecode servono solo per l’abbinamento.
string
Un endpoint https che da questo momento riceve gli eventi webhook di questo progetto e sostituisce l’endpoint configurato sull’account.Predefinito: L’endpoint già salvato nel progetto, poi l’endpoint webhook dell’account.
boolean
Mantenere l’audio di sottofondo originale (musica, ambiente) sotto le voci generate.Predefinito:
trueboolean
Mantenere la voce originale a basso volume sotto la voce generata.Predefinito:
falsenumber
Volume della voce originale da
1 a 70 quando keepOriginalVoice è attivo.Predefinito: 30string
Strategia vocale:
cloning (clonare le voci dei parlanti del progetto) o custom (usare una voce del catalogo o la tua voce personalizzata salvata).Predefinito: cloningstring
Obbligatorio quando
voiceMode è custom. Usa un ID di dubbing_voices_list: una voce del catalogo o una voce personalizzata salvata dall’account
autenticato. La fatturazione del team non concede accesso alle voci salvate degli altri membri.string
Modalità di isolamento della voce quando
keepBackgroundMusic è attivo: studio o realistic.Predefinito: studioboolean
Masterizzare i sottotitoli nel video di output. Richiede un progetto video.Predefinito:
falsestring
Testo dei sottotitoli quando
subtitles è attivo: translated (il tuo SRT) o original (la trascrizione di origine).Predefinito: translatedstring
Esegui la sincronizzazione labiale quando il doppiaggio è pronto:
standard, pro o studio. Le regole di piano, durata e crediti sono le stesse di Avvia traduzione. Richiede un progetto video.Predefinito: ometti il campo per saltare la sincronizzazione labiale.boolean
Abilita il rilevamento del parlante attivo per l’esecuzione di sincronizzazione labiale richiesta.Predefinito:
falseobject
Regolazione fine del clonaggio vocale, come oggetto JSON con
stability e similarity tra 0 e 1. Solo con voiceMode: "cloning". Vedi Avvia traduzione per il significato di ciascun valore.array
Intervalli del tempo sorgente da lasciare nella lingua originale, come
[{ "startTime": 10.2, "endTime": 12.8 }]. Richiede un progetto video e keepBackgroundMusic: true, non può essere combinato con keepOriginalVoice e non può sovrapporsi ai segmenti della trascrizione.Risposta
boolean
obbligatorio
Sempre
true per le richieste riuscite.string
obbligatorio
Una conferma leggibile.
string
obbligatorio
Il progetto che viene doppiato.
string
obbligatorio
Il lavoro di traduzione usato per
targetLanguage. Corrisponde a workId negli endpoint di stato, dettagli e trascrizione.number
obbligatorio
Stima approssimativa dell’elaborazione in minuti: cinque minuti di elaborazione per ogni minuto iniziato del media sorgente.
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
}
Seguire l’esecuzione
Il progetto passa al flussotranslation non appena parte il doppiaggio, quindi Ottieni lo stato della traduzione segue la nuova esecuzione: status passa da processing a success (con translatedVideoUrl e translatedAudioUrl) oppure a failed (con error). I webhook project.translation.completed e project.translation.failed vengono inviati con lo stesso targetLanguage. In Ottieni dettagli del progetto, la versione tradotta riporta settings.dubbingMode: "dub-only" e settings.smartSync: false.
Gli errori di allineamento compaiono dopo l’accettazione della richiesta POST. L’endpoint di stato restituisce status: "failed" con error.code e error.message; il webhook project.translation.failed contiene lo stesso codice e messaggio. TRANSLATED_SRT_UNMATCHED_CUES indica nel messaggio i numeri dei cue senza corrispondenza e TRANSLATED_SRT_MISSING_SEGMENTS gli indici dei segmenti senza cue. Queste risposte asincrone non includono un campo details strutturato. Correggi l’SRT e richiama l’endpoint: la versione non riuscita resta nella cronologia e ne viene creata una nuova.
Controllare il ritmo
Esporta la trascrizione tradotta in JSON con Esporta trascrizione del progetto. Ogni segmento includefinalSpeedFactor, il rapporto tra il parlato generato e la finestra del segmento. Accorcia i cue che restano sopra circa 1.3, poi esegui di nuovo il doppiaggio con l’SRT rivisto.
Flusso di esempio
Un’automazione tipica (per esempio uno scenario n8n o Make) concatena gli endpoint come segue:POST /v1/projectscon il media,targetLanguagee unoriginalLanguageesplicito (solo trascrizione).- Interroga
GET /v1/translate/{projectId}/statusfinchétranscriptionStatusèsuccess, oppure attendi il webhookproject.created. POST /v1/projects/{projectId}/transcriptcon{ "source": "original", "outputFormat": "srt" }e traduci i cue mantenendo numerazione e timecode.POST /v1/projects/{projectId}/dubcon l’SRT tradotto.- Interroga l’endpoint di stato finché
statusèsuccess, oppure attendiproject.translation.completed. - Scarica
translatedVideoUrl(oppurelipSync.videoUrlse è stata richiesta la sincronizzazione labiale). DELETE /v1/translate/{projectId}quando gli output sono salvati dalla tua parte.
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']
Errori
| Stato | Codice | Descrizione |
|---|---|---|
| 400 | VALIDATION_ERROR | Un campo del corpo manca o non è valido (details elenca ogni campo) |
| 400 | INVALID_TRANSLATED_SRT | translatedSrt non contiene cue SRT validi |
| 400 | INVALID_BOOLEAN_VALUE | Un’opzione booleana non è stata inviata come booleano JSON |
| 400 | INVALID_NUMBER_VALUE | Un’opzione numerica non è stata inviata come numero JSON |
| 400 | DURATION_DETECTION_FAILED | La durata del media salvata del progetto non è disponibile |
| 400 | VOICE_ID_REQUIRED | La modalità voci personalizzate è stata selezionata senza un ID voce |
| 400 | VOICE_ID_NOT_ALLOWED_WITH_CLONING | Un ID voce è stato combinato con la clonazione vocale |
| 400 | VOICE_CLONING_SETTINGS_NOT_ALLOWED | Le impostazioni di clonazione sono state combinate con la modalità voci personalizzate |
| 400 | TRANSLATION_TIME_SKIP_CONFLICT | I salti temporali sono in conflitto con un’altra opzione audio |
| 400 | TRANSLATION_TIME_SKIP_REQUIRES_BACKGROUND | I salti temporali richiedono audio di sottofondo |
| 400 | TRANSLATION_TIME_SKIP_OUT_OF_RANGE | Un salto temporale si estende oltre la durata del file multimediale |
| 400 | SUBTITLES_NOT_AVAILABLE_FOR_AUDIO | Sono stati richiesti sottotitoli impressi per l’input audio |
| 400 | LIPSYNC_NOT_AVAILABLE_FOR_AUDIO | È stata richiesta la sincronizzazione labiale per l’input audio |
| 400 | TRANSLATION_TIME_SKIP_NOT_AVAILABLE_FOR_AUDIO | Sono stati richiesti salti temporali per l’input audio |
| 400 | LIPSYNC_VIDEO_TOO_LONG | La sincronizzazione labiale è stata richiesta per file multimediali più lunghi della durata supportata |
| 401 | MISSING_API_KEY | La chiave API è richiesta |
| 401 | INVALID_API_KEY_FORMAT | La chiave API deve iniziare con vc_ |
| 401 | INVALID_API_KEY | La chiave API fornita non è valida |
| 403 | SUBSCRIPTION_REQUIRED | L’accesso API richiede un piano Starter o superiore |
| 403 | FORBIDDEN | Non hai il permesso di accedere al progetto |
| 403 | INSUFFICIENT_CREDITS | Crediti insufficienti per doppiare questo progetto |
| 403 | CUSTOM_VOICE_ACCESS_DENIED | La voce selezionata non è una voce del catalogo né una voce personalizzata salvata dall’account autenticato. |
| 403 | LIPSYNC_MODE_ACCESS_DENIED | La modalità di sincronizzazione labiale premium non è disponibile nel piano attuale |
| 404 | PROJECT_NOT_FOUND | Il progetto non esiste |
| 409 | DUB_ONLY_REQUIRES_TRANSCRIPTION | La trascrizione del progetto è ancora in elaborazione oppure non è riuscita |
| 409 | TRANSLATION_ALREADY_IN_PROGRESS | Un doppiaggio è già in corso per questa lingua nel progetto |
| 429 | RATE_LIMIT_EXCEEDED | Troppe richieste (limite: 10 richieste al minuto) |
| 429 | CONCURRENT_TRANSLATION_LIMIT_REACHED | Limite di traduzioni simultanee dell’account raggiunto; vedi details.limit |
| 500 | INTERNAL_ERROR | Errore imprevisto del server |
TRANSLATED_SRT_UNMATCHED_CUES, TRANSLATED_SRT_MISSING_SEGMENTS) sono restituiti dall’endpoint di stato e dal webhook di errore, non da questa richiesta.Questa pagina è stata utile?

