¿Qué hace ffmpeg-pipeline?
La habilidad de pegamento. Convierte imágenes fijas generadas (o proporcionadas) en un MP4 animado con narración, y realiza las tareas multimedia rutinarias que un agente encuentra constantemente.
Requiere ffmpeg + ffprobe. Necesita anon-image para el modo de generación y anon-audio para --narration; ambos se descubren automáticamente como hermanos, y ambos son opcionales si pasas --images / --audio directamente.
Comandos
| Comando | Qué hace |
|---|---|
video | imágenes fijas (generadas o de --images) → MP4 con movimiento zoompan + crossfades, narración opcional y pista musical |
slideshow | imágenes existentes → MP4 |
mux | adjuntar una pista de audio a un vídeo, repitiendo/rellenando para ajustar |
frames | extraer fotogramas cada N segundos |
sheet | hoja de contacto (N fotogramas espaciados uniformemente con marcas de tiempo) |
gif | GIF recortado, optimizado con paleta, desde cualquier sección |
normalize | normalizar el volumen del audio a −16 LUFS |
speed | cambiar la velocidad del audio sin alterar el tono (atempo encadenado) |
info | resumen de ffprobe en una línea |
probe | verificación de dependencias |
Inicio rápido
# todo el pipeline en una sola llamada: 3 tomas generadas, 4 s cada una, narrado
vidkit.py video "un faro en un acantilado de basalto al atardecer, cinematográfico" -o historia.mp4 \
--shots 3 --seconds 4 --ratio 16:9 \
--narration "En alguna costa fría, un faro mantiene su vigilia." \
--voice es-ES-AlvaroNeural
# reutilizar imágenes que ya tienes
vidkit.py video --images fotos/ -o salida.mp4 --seconds 3 --music fondo.mp3
# cirugía multimedia
vidkit.py mux clip.mp4 voz_en_off.mp3 -o final.mp4
vidkit.py sheet final.mp4 -o preview.jpg --cols 4 --count 8
vidkit.py gif final.mp4 -o teaser.gif --start 1 --dur 2.5 --width 480
vidkit.py normalize voz_en_off.mp3 -o limpio.mp3
vidkit.py info final.mp4
Cálculos de tiempo (para que puedas predecir la salida)
Con N tomas de S segundos y un crossfade de 0,8 s:
duración = N*S - (N-1)*0,8
3 × 4 s → 10,4 s. Si la narración es más larga que el vídeo, el vídeo se repite para cubrirla (-stream_loop). Si es más corta, el audio se rellena con silencio para que nunca pierdas el final. Ambos casos se manejan automáticamente — no añadas -shortest por tu cuenta.
Reglas de decisión
- Relación de aspecto:
16:9para YouTube/web,9:16para Shorts/Reels/TikTok,1:1para feeds y miniaturas. Todo se escala para cubrir y luego se recorta, así que las imágenes fuente de cualquier forma sobreviven sin bandas negras. - Segundos por toma: 3–4 s es correcto para una imagen fija; más de 6 s de una imagen estática se siente muerto. Si necesitas más duración, añade tomas, no segundos.
- Pista musical: pasa
--musicy se mezcla al 12 % por debajo de la voz. No mezcles dos fuentes fuertes; normaliza primero. - GIF: mantén el ancho ≤ 480 y la duración ≤ 3 s, o el archivo excede los límites del chat.
Modos de fallo
| Síntoma | Causa | Solución |
|---|---|---|
missing dependency: ffmpeg | no instalado | apt install ffmpeg (o brew install ffmpeg) |
ffmpeg failed: … Invalid argument en zoompan | dimensiones de origen impares | el filtro ya escala a W*2; si lo editaste, mantén números pares |
| la salida es silenciosa | archivo de narración faltante/vacío | verifica la ruta; --narration acepta texto o una ruta de audio |
| salida mucho más corta de lo esperado | audio más corto que el vídeo y algo añadió -shortest | elimínalo; vidkit.py lo rellena en su lugar |
contact sheet necesita Pillow | no hay Pillow | pip install pillow, o usa frames + tu propia hoja |
Notas para el agente
- Renderiza a 720p a menos que el usuario pida más. Es 4× más rápido y nadie nota la diferencia en una pantalla de portátil.
- Siempre ejecuta
infoen el artefacto final y cita la duración real, resolución y tamaño al usuario — detecta fallos silenciosos. - Entrega la ruta del MP4; no lo incrustes. El archivo es el artefacto.