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-minuteso 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:
-
Extraer audio (16 kHz, mono):
ffmpeg -y -i input.mp4 -ar 16000 -ac 1 -c:a pcm_s16le audio16k.wav -
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 .Generaaudio16k.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. -
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. -
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. -
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.mp4Luego 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 mostrarvideo, audio). -
Quemar subtítulos duros:
python3 <skill>/scripts/burn_subtitles.py output_temp.mp4 subtitle_synced.srt output_final.mp4Renderiza los subtítulos traducidos permanentemente en el video. -
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) -> usardub.py --srt existing.srtpara 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 defectozh); el idioma TTS dedub_segments.pyse 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 desubtitles=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(oturbo), no retroceder abase/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.txttiene exactamente el mismo número de líneas que segmentos SRT. -
dubbing.wavysubtitle_synced.srthan sido generados. -
ffprobemuestra 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, condub.pyes<nombre_video>_<idioma_destino>.mp4), con doblaje y subtítulos duros en el idioma destino; opcionalmente se puede conservarsubtitle_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, generato_translate.txty solicita a la IA que traduzca atranslated.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]. Devuelvedubbing.wavysubtitle_synced.srtalineados; 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.pyy especificar--fontcon 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— Proporcionamlx_audio.tts.generatesubyacente, del cual depende el doblaje de este skill.video-minutes— Convierte video en actas estructuradas; usar cuando solo se necesita transcripción/resumen.