Communitygithub.com

video-dubbing: traducción de video, doblaje y sincronización de…

Pipeline local de doblaje de video: extracción a 16kHz → ASR → traducción automática → TTS segmentado → mezcla → quema de subtítulos. Sincronización bloqueada por marcas de tiempo.

¿Qué es video-dubbing: traducción de video, doblaje y sincronización de…?

Este skill implementa un flujo de trabajo completo para localizar un video a otro idioma, combinando reconocimiento de voz (ASR), traducción automática, síntesis de voz (TTS) y postproducción de video. Es ideal para desarrolladores y usuarios que necesitan generar un video listo para publicar con doblaje y subtítulos sincronizados, sin requerir ajustes manuales. Soporta plataformas como Claude Code, Cursor y Codex, y utiliza herramientas como whisper para ASR, ffmpeg para manipulación de video y audio, y scripts Python personalizados para la segmentación y quema de subtítulos. El pipeline preserva las marcas de tiempo originales del ASR, asegurando que el doblaje y los subtítulos coincidan perfectamente con la imagen. Incluye opciones para elegir el motor ASR (whisper o Qwen3-ASR para mejor reconocimiento de chino), saltar pasos si ya se tienen subtítulos, y evitar la quema de subtítulos si no es necesaria. La validación final verifica la sincronización y la correcta sustitución de la pista de audio.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/renky1025/agent-skills/tree/main/video-dubbing

Preguntar en tu IA favorita

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

Documentación

video-dubbing: traducción de video, doblaje y sincronización de subtítulos

Propósito

Localizar un video completo a otro idioma: reconocer el audio original, traducirlo, generar una pista de doblaje con TTS en el idioma destino, y manteniendo las marcas de tiempo originales, sintetizar la pista de audio y quemar los subtítulos traducidos en el video. El resultado es un archivo de video único listo para publicar, con doblaje y subtítulos naturalmente sincronizados, sin necesidad de ajustes secundarios.

Cuándo usar

  • El usuario solicita traducir un video a otro idioma y que tenga doblaje (no solo subtítulos).
  • Se necesita agregar doblaje + subtítulos sincronizados en el idioma destino (bilingüe o solo traducción).
  • Palabras clave: traducción de video, doblaje de video, subtítulos traducidos, generar doblaje en otro idioma, subtítulos bilingües, dub a video, translate a video, foreign-language voiceover.
  • Cualquier flujo de trabajo ASR -> traducción -> TTS -> síntesis de video.

Cuándo NO usar

  • Solo se necesita transcripción, sin traducción ni doblaje -> usar video-minutes o whisper directamente.
  • Solo se necesita sintetizar texto a audio, sin video -> usar mlx-tts.
  • Se necesita preservar la música de fondo/efectos de sonido originales con mezcla profesional (separación de voces) -> este skill no aplica Demucs por defecto; se requiere procesamiento adicional.
  • El video no tiene pista de audio o la calidad es demasiado baja para reconocer.

Flujo de trabajo

Se recomienda usar el script de orquestación <skill>/scripts/dub.py (ver ## Scripts), que ejecuta los siguientes pasos en orden y pausa en la traducción para que la IA la realice. Para ejecución manual, siga estos pasos:

  1. Extraer audio (16 kHz, mono): ffmpeg -y -i input.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio16k.wav

  2. Transcripción ASR (con marcas de tiempo precisas por segmento): whisper audio16k.wav --model large-v3-turbo --language <idioma_origen> --output_format srt --output_dir . Genera audio16k.srt, con marcas de tiempo naturalmente alineadas al video original. Para mejor reconocimiento de chino, se puede usar Qwen3-ASR (pip install qwen-asr) con <skill>/scripts/qwen3_asr.py.

  3. Traducir subtítulos (realizado por IA): Leer el SRT, traducir segmento por segmento. Cada segmento SRT debe generar una línea de traducción, manteniendo el orden estrictamente. Primero contar el número de segmentos (ej. 27 segmentos -> 27 líneas), guardar como translated.txt, y verificar que el número de líneas coincida antes de continuar.

  4. Generar doblaje: python3 <skill>/scripts/dub_segments.py audio16k.srt translated.txt dubbing.wav subtitle_synced.srt --lang <idioma_destino> El script: usa el primer segmento como referencia de timbre para mantener consistencia de voz; preserva las marcas de tiempo originales para sincronizar subtítulos con imagen; solo aplica cambios de velocidad (atempo 0.88–1.20) en segmentos que exceden su espacio; puentea intervalos adyacentes menores a 1s para un sonido natural.

  5. Mezclar pista de doblaje con video:

    ffmpeg -y -i input.mp4 -i dubbing.wav \
      -map 0:v:0 -map 1:a:0 \
      -c:v copy -c:a aac -b:a 192k -shortest output_temp.mp4
    

    Luego confirmar que la pista de audio ha sido reemplazada: ffprobe -v error -show_entries stream=codec_type -of csv=p=0 output_temp.mp4 (debe mostrar video, audio).

  6. Quemar subtítulos duros: python3 <skill>/scripts/burn_subtitles.py output_temp.mp4 subtitle_synced.srt output_final.mp4 Renderiza los subtítulos traducidos permanentemente en el video.

  7. Limpiar (opcional): Eliminar archivos intermedios como audio16k.wav, audio16k.srt, translated.txt, dubbing.wav, subtitle_synced.srt, output_temp.mp4, etc.

Reglas de decisión

  • Para ejecución completa de un solo paso -> usar dub.py; solo para repetir un paso específico (ej. si ya se tiene SRT) -> usar dub.py --srt existing.srt para saltar pasos.
  • Motor ASR: por defecto --asr whisper (large-v3-turbo); si se requiere alta precisión para chino -> --asr qwen3.
  • Si no se necesitan subtítulos duros -> dub.py --no-burn (solo hasta la mezcla de pistas de audio).
  • Idioma destino definido por --target-lang (por defecto zh); el idioma TTS de dub_segments.py se define con --lang.
  • La traducción debe ser realizada por IA y estrictamente 1:1 con los segmentos SRT; si el número de líneas no coincide, el script reporta error y termina, no se debe eludir.
  • Si los subtítulos no aparecen o el chino se muestra como cuadros -> usar burn_subtitles.py (renderiza con moviepy, busca automáticamente fuentes chinas), no depender de subtitles= de ffmpeg (falla silenciosamente si falta libass).
  • Si la duración del doblaje excede el espacio disponible -> usar el atempo segmentado del script, no aplicar cambio de velocidad global a toda la pista.

Restricciones

  • Las marcas de tiempo deben reutilizar los resultados ASR originales, prohibido realizar un nuevo ASR sobre el doblaje para obtener marcas.
  • El número de líneas de traducción debe ser igual al número de segmentos SRT (1:1), de lo contrario se detiene.
  • Al mezclar pistas, usar explícitamente -map 0:v:0 -map 1:a:0, de lo contrario se conserva la pista de audio original.
  • ASR debe usar large-v3-turbo (o turbo), no retroceder a base/tiny.
  • Los cambios de velocidad se realizan solo a nivel de segmento, en el rango 0.88–1.20x; prohibido aplicar atempo global.
  • Por defecto no se realiza separación de voces del fondo musical; si el usuario lo solicita, debe indicarse explícitamente que se requiere procesamiento adicional.

Verificación

Antes de entregar, verificar cada punto:

  • translated.txt tiene exactamente el mismo número de líneas que segmentos SRT.
  • dubbing.wav y subtitle_synced.srt han sido generados.
  • ffprobe muestra que el video final contiene flujos de video y audio, y que el audio ha sido reemplazado.
  • Los subtítulos están quemados en el video (no son subtítulos blandos externos), sin cuadros en caracteres chinos.
  • El doblaje y la imagen están sincronizados en varios puntos aleatorios de muestra.
  • No se han eliminado archivos fuente proporcionados por el usuario.

Salida

  • Resultado: Un archivo de video localizado (por defecto output_final.mp4, con dub.py es <nombre_video>_<idioma_destino>.mp4), con doblaje y subtítulos duros en el idioma destino; opcionalmente se puede conservar subtitle_synced.srt.
  • Finalizado cuando: La pista de audio ha sido reemplazada, los subtítulos están quemados, el audio y el video están sincronizados en los puntos de muestra, y ffprobe ha verificado.
  • Evidencia: Ruta del archivo final; número de segmentos SRT y líneas de traducción; lista de flujos de ffprobe; puntos de sincronización muestreados.

Referencias

Cargar según sea necesario, no leer todo de antemano:

  • references/pipeline-design.md — Leer cuando sea necesario explicar o ajustar el comportamiento del pipeline (por qué se preservan las marcas de tiempo, cambio de velocidad segmentado, por defecto no separación de voces, lista de productos y dependencias).
  • references/troubleshooting.md — Leer cuando ocurran errores reales, desincronización de audio y video, subtítulos que no aparecen o caracteres chinos como cuadros.

Scripts

  • <skill>/scripts/dub.py — Orquestación de extremo a extremo. Uso: python3 <skill>/scripts/dub.py input.mp4 --source-lang en --target-lang zh [--asr whisper|qwen3] [--srt existing.srt] [-o out.mp4] [--font-size 28] [--no-burn] [--keep-temp]. Al llegar al paso de traducción, genera to_translate.txt y solicita a la IA que traduzca a translated.txt, luego continúa; devuelve la ruta del video final y la ruta de subtítulos.
  • <skill>/scripts/dub_segments.py — TTS segmentado + alineación de marcas de tiempo. Uso: python3 <skill>/scripts/dub_segments.py original.srt translated.txt out_dub.wav out_synced.srt [--lang zh] [--min-atempo 0.88] [--max-atempo 1.20] [--gap-bridge 1.0] [--keep-temp]. Devuelve dubbing.wav y subtitle_synced.srt alineados; si el número de líneas de traducción no coincide, termina con código de salida 1.
  • <skill>/scripts/burn_subtitles.py — Quemar subtítulos duros con moviepy. Uso: python3 <skill>/scripts/burn_subtitles.py input.mp4 subtitles.srt output.mp4 [--font <ruta>] [--font-size 28]. Devuelve el video con subtítulos quemados; si no se especifica --font, detecta automáticamente fuentes chinas.
  • <skill>/scripts/qwen3_asr.py — CLI compatible con whisper para Qwen3-ASR, mejor reconocimiento de chino. Uso: python3 <skill>/scripts/qwen3_asr.py audio.wav [--model 0.6B|1.7B] [--language zh] [-f srt|vtt|txt|json|tsv|all] [-o directorio_salida] [--device cuda:0|mps|cpu] [--dtype float16|bfloat16|float32]. Devuelve archivos de subtítulos/texto en el formato especificado. Alias de modelos: turbo/tiny/base/small -> Qwen3-ASR-0.6B, medium/large -> Qwen3-ASR-1.7B.

Solución de problemas

  • El doblaje no se ha reemplazado / aún se escucha el original -> Al mezclar con ffmpeg faltó -map 0:v:0 -map 1:a:0.
  • Los subtítulos no aparecen o los caracteres chinos se muestran como cuadros -> Usar burn_subtitles.py y especificar --font con una fuente china.
  • El número de líneas de traducción no coincide con los segmentos SRT -> El script reportará error y terminará; completar hasta que sea 1:1.
  • Lista completa de errores en references/troubleshooting.md.

Skills relacionados

  • mlx-tts — Proporciona mlx_audio.tts.generate subyacente, del cual depende el doblaje de este skill.
  • video-minutes — Convierte video en actas estructuradas; usar cuando solo se necesita transcripción/resumen.

Skills relacionados