Communitygithub.com

rodrvc/marca-personal

Dobla audio y video a otros idiomas usando la API de Doblaje de ElevenLabs (dubbing_v2), preservando las voces de los hablantes originales. Úsalo para traducir videos, podcasts o grabaciones a otros idiomas, localizar contenido multimedia, revisar o corregir transcripciones y traducciones de doblaje, o regenerar un doblaje después de ediciones.

¿Qué es marca-personal?

Esta habilidad dobla audio o video a otros idiomas mientras preserva las voces de los hablantes originales mediante la API de Doblaje de ElevenLabs (dubbing_v2). Está diseñada para creadores de contenido, desarrolladores y equipos de localización que necesitan traducir y doblar medios como videos promocionales, podcasts, entrevistas o grabaciones de capacitación. Compatible con plataformas como Claude Code, Cursor, Codex e implementaciones personalizadas mediante REST, SDKs de Python y JavaScript, o cURL. El flujo de trabajo recomendado comienza creando un proyecto desde un archivo local o una URL, esperando a que la transcripción esté lista, revisando y corrigiendo la transcripción fuente, agregando uno o más idiomas objetivo, refinando las traducciones por segmento y regenerando el doblaje según sea necesario. Solo los espacios de trabajo empresariales pueden editar transcripciones y regenerar; otros planes pueden crear proyectos y agregar idiomas. La habilidad también explica los conceptos clave como proyecto, transcripción fuente, idioma, y revisión de salida, proporcionando ejemplos de código prácticos para una implementación rápida.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/rodrvc/personal-brand/tree/HEAD/.claude/skills/dubbing

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Doblaje con ElevenLabs

Dobla audio o video a otros idiomas preservando las voces de los hablantes originales. Crea un proyecto desde un archivo o URL, revisa y edita la transcripción fuente, agrega uno o más idiomas objetivo, refina las traducciones por segmento y regenera las salidas.

Importante: Usa la API de Proyectos de Doblaje — elevenlabs.dubbing.project.* en los SDKs, o los endpoints REST /v1/dubbing/project. No uses la superficie de doblaje heredada v1 (client.dubbing.create(), client.dubbing.get(), client.dubbing.audio.get(), o rutas simples /v1/dubbing) — esa es la API de doblaje antigua, ahora bajo Legado en la referencia de la API.

Configuración: Consulta la Guía de instalación. La URL base REST es https://api.elevenlabs.io con tu clave API en el encabezado xi-api-key; los SDKs leen ELEVENLABS_API_KEY automáticamente.

Conceptos

ConceptoSignificado
ProyectoUn medio fuente (archivo o URL) más su transcripción fuente. Se prepara (transcribe) una vez, luego permanece en ready mientras agregas idiomas.
Transcripción fuenteSegmentos editables (texto, hablante, tiempo) transcritos de la fuente. La fuente de verdad única de la que se traduce cada idioma.
Idioma (objetivo)Un idioma de salida doblado. Cada uno tiene su propia transcripción (segmentos fuente + una traducción por segmento) y su propio audio doblado.
RevisionesContadores monótonos independientes. La revision del proyecto aumenta con ediciones en la transcripción fuente; la revision de un idioma aumenta con ediciones de traducción o ediciones fuente que lo afectan. La output_revision de un idioma es la revisión con la que se generó su audio actual — cuando está detrás de revision, la salida está desactualizada.

Orden de operaciones recomendado: finaliza la transcripción fuente antes de agregar cualquier idioma. Las traducciones se producen a partir de la fuente, así que corregir la fuente primero significa que cada idioma comienza desde el texto correcto — editar la fuente después de que un idioma se complete lo marca como stale y requiere una regeneración (con costo).

Empresarial: La edición de transcripciones y la regeneración están disponibles solo para espacios de trabajo empresariales. La creación de proyectos, agregar idiomas y descargar doblajes funcionan en todos los planes.

Flujo de trabajo

  1. Crea el proyecto desde un archivo o URL → queued
  2. Consulta el proyecto hasta que esté ready
  3. Revisa y finaliza la transcripción fuente (edita/añade/elimina segmentos)
  4. Agrega un idioma por objetivo → queued → processing → completed
  5. Descarga el outputs.lossless_audio de cada idioma cuando esté completed
  6. Refina las traducciones por segmento si es necesario → el idioma pasa a stale
  7. Regenera el idioma → completed nuevamente con salida fresca

Inicio rápido (Python)

import os
import time
import requests
from elevenlabs.client import ElevenLabs

elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))

# 1. Crea un proyecto desde un archivo local (o pasa source_url=... en lugar de archivo)
with open("promo.mp4", "rb") as f:
    project = elevenlabs.dubbing.project.create(
        file=f,
        source_language="en",
        reference="Video marketing Q3",
    )

# 2. Espera a que el medio fuente sea transcrito
while True:
    project = elevenlabs.dubbing.project.get(project.project_id)
    if project.status == "ready":
        break
    if project.status == "failed":
        raise RuntimeError("La preparación del proyecto falló")
    time.sleep(5)

# 3. Agrega un idioma objetivo español
language = elevenlabs.dubbing.project.language.create(
    project.project_id,
    target_language="es",
)

# 4. Espera a que el doblaje termine de generarse
while True:
    language = elevenlabs.dubbing.project.language.get(
        project.project_id, language.language_id
    )
    if language.status == "completed":
        break
    if language.status == "failed":
        raise RuntimeError("La generación del doblaje falló")
    time.sleep(5)

# 5. Descarga el audio doblado (URL firmada, válida ~1 hora — vuelve a obtener el idioma para una nueva)
audio = requests.get(language.outputs.lossless_audio)
with open("promo_es.wav", "wb") as f:
    f.write(audio.content)

Inicio rápido (JavaScript)

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { writeFile } from "fs/promises";

const elevenlabs = new ElevenLabsClient();

// 1. Crea un proyecto (se muestra sourceUrl; la subida de archivos también es compatible)
let project = await elevenlabs.dubbing.project.create({
  sourceUrl: "https://example.com/promo.mp4",
  sourceLanguage: "en",
  reference: "Video marketing Q3",
});

// 2. Espera a que el medio fuente sea transcrito
while (true) {
  project = await elevenlabs.dubbing.project.get(project.projectId);
  if (project.status === "ready") break;
  if (project.status === "failed") throw new Error("La preparación del proyecto falló");
  await new Promise((resolve) => setTimeout(resolve, 5000));
}

// 3. Agrega un idioma objetivo español
let language = await elevenlabs.dubbing.project.language.create(project.projectId, {
  targetLanguage: "es",
});

// 4. Espera a que el doblaje termine de generarse
while (true) {
  language = await elevenlabs.dubbing.project.language.get(project.projectId, language.languageId);
  if (language.status === "completed") break;
  if (language.status === "failed") throw new Error("La generación del doblaje falló");
  await new Promise((resolve) => setTimeout(resolve, 5000));
}

// 5. Descarga el audio doblado desde la URL firmada
const response = await fetch(language.outputs!.losslessAudio!);
await writeFile("promo_es.wav", Buffer.from(await response.arrayBuffer()));

Inicio rápido (cURL)

# 1. Crea un proyecto (usa -F "source_url=https://..." en lugar de archivo para doblar desde una URL)
curl -X POST "https://api.elevenlabs.io/v1/dubbing/project" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -F "[email protected]" \
  -F "source_language=en"
# → {"project_id": "proj_...", "status": "queued", ...}

# 2. Consulta hasta que el estado sea "ready"
curl "https://api.elevenlabs.io/v1/dubbing/project/proj_..." \
  -H "xi-api-key: $ELEVENLABS_API_KEY"

# 3. Agrega un idioma objetivo
curl -X POST "https://api.elevenlabs.io/v1/dubbing/project/proj_.../language" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_language": "es"}'

# 4. Consulta el idioma hasta que esté "completed", luego descarga outputs.lossless_audio
curl "https://api.elevenlabs.io/v1/dubbing/project/proj_.../language/lang_..." \
  -H "xi-api-key: $ELEVENLABS_API_KEY"

Opciones de creación

POST /v1/dubbing/project acepta multipart/form-data con ya sea file o source_url (no ambos):

CampoRequeridoNotas
fileuno de file/source_urlMedio fuente a doblar (audio o video), hasta 3 GiB
source_urluno de file/source_urlURL pública para obtener el medio fuente
source_languagenoCódigo ISO 639 (ej. en). Omitir para detección automática — el idioma detectado se informa en el campo language de la transcripción fuente
referencenoEtiqueta libre para identificar el proyecto (máx. 500 caracteres)
model_idnodubbing_v2 (predeterminado)
target_languagenoOpcionalmente encola el primer idioma objetivo en la creación; agrega más con language.create
keytermsnoTérminos para sesgar la transcripción/traducción (nombres de productos/marcas). Hasta 100 términos de 200 caracteres cada uno; repite el campo una vez por término en multipart

Editar la transcripción fuente

Una vez que el proyecto está ready, lee la transcripción, luego corrígela antes de agregar idiomas. Cada edición aumenta la revision del proyecto. Cada segmento tiene un id estable usado para editarlo o eliminarlo. (Solo espacios de trabajo empresariales).

# Lee la transcripción fuente
transcript = elevenlabs.dubbing.project.transcript.get(project_id)

# Corrige el texto de un segmento — envía solo los campos a cambiar (text, speaker_id, start_s, end_s)
elevenlabs.dubbing.project.transcript.update_segment(
    project_id,
    segment_id=transcript.segments[0].id,
    text="Bienvenido a nuestra última demostración de producto.",
)

# Agrega un segmento (reutiliza un speaker_id existente para que se doble con la voz de ese hablante)
added = elevenlabs.dubbing.project.transcript.create_segment(
    project_id,
    text="Gracias por ver.",
    speaker_id=transcript.segments[0].speaker_id,
    start_s=40.0,
    end_s=42.0,
)

# Elimina un segmento
elevenlabs.dubbing.project.transcript.delete_segment(project_id, segment_id=added.segment.id)

Vía REST: GET /v1/dubbing/project/{project_id}/transcript, luego PATCH .../transcript/segment/{segment_id} solo con los campos cambiados:

curl -X PATCH "https://api.elevenlabs.io/v1/dubbing/project/{project_id}/transcript/segment/{segment_id}" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "Bienvenido a nuestra última demostración de producto."}'

Refinar traducciones y regenerar

La transcripción de un idioma empareja cada segmento fuente con su translation (null = aún no traducido; los ids de segmento coinciden con la fuente). Edita una sola traducción, luego regenera. (Solo espacios de trabajo empresariales).

# Lee las traducciones del idioma
target = elevenlabs.dubbing.project.language.transcript.get(project_id, language_id)

# Refina una sola traducción (pasa translation=None para limpiarla y marcarla para retraducción)
elevenlabs.dubbing.project.language.transcript.update_segment(
    project_id,
    language_id,
    segment_id=target.segments[0].id,
    translation="Bienvenido a nuestra última demostración de producto.",
)

# Regenera el doblaje desde la transcripción actual (con costo como una generación)
elevenlabs.dubbing.project.language.transcript.regenerate(project_id, language_id)

Vía REST: PATCH /v1/dubbing/project/{project_id}/language/{language_id}/transcript/segment/{segment_id} con {"translation": "..."}, luego POST .../language/{language_id}/transcript/regenerate (devuelve 202 Accepted).

Una edición de traducción afecta solo a ese idioma. Después de la edición, un idioma completed se vuelve stale — sigue sirviendo su salida anterior hasta que regeneres. Consulta hasta que esté completed; output_revision entonces es igual a revision y outputs.lossless_audio refleja la transcripción actual.

Doblaje en múltiples idiomas

Agrega un objetivo de idioma por idioma — cada uno se genera de forma independiente. Rastrea todos con language.list en lugar de consultar uno por uno:

for lang in ["es", "fr", "de", "ja"]:
    elevenlabs.dubbing.project.language.create(project_id, target_language=lang)

while True:
    result = elevenlabs.dubbing.project.language.list(project_id)
    if not any(l.status in ("queued", "processing") for l in result.languages):
        break
    time.sleep(5)

Estados

Proyecto:

EstadoSignificado
queuedCreado; obtención fuente + preparación encolada
preparingPreparación (transcripción) en ejecución
readyTranscripción fuente disponible; agrega/genera idiomas. Los proyectos permanecen ready — el progreso por idioma reside en los idiomas
failedPreparación falló (ej. la fuente no pudo obtenerse o decodificarse)

Idioma:

EstadoSignificado
queuedEsperando que el proyecto esté ready, o a un trabajador de generación
processingEl doblaje se está generando
completedTerminado; outputs poblado con una URL de descarga firmada (válida ~1 hora — vuelve a obtener para una nueva)
stalePreviamente completado, pero la transcripción cambió; mantiene la última salida hasta que se regenere
failedGeneración falló

Puedes agregar un idioma antes de que el proyecto esté ready — permanece queued y comienza automáticamente una vez que el proyecto esté ready. Agregar un idioma acepta model_id opcional (predeterminado al del proyecto) y voice_settings (ej. {"cloning_strength": 7}, rango 0–10, predeterminado 7 — controla qué tan fuerte clonan las voces dobladas a las voces fuente).

Manejo de errores

  • 401: Clave API no válida
  • 409 Conflict en regenerar: El proyecto no está ready o el idioma no está estable (ej. ya generando) — espera y reintenta
  • URL de descarga expirada: outputs.lossless_audio está firmada y es válida ~1 hora; vuelve a obtener el idioma para una URL nueva
  • Edición de transcripción / regeneración no disponible: Estos endpoints son solo empresariales — en otros planes, crea el proyecto con una fuente finalizada y agrega idiomas directamente

Referencias

Skills relacionados