FFmpeg Esenciales
Siempre sondear primero, nunca sobrescribir la entrada, y recodificar al cortar a menos que se indique lo contrario.
Sondear
# Resumen legible
ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,r_frame_rate,sample_rate -show_entries format=duration,size -of default=nw=1 input.mp4
# Legible por máquina
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
Recortar
# Empezar en 30 s, mantener 15 s. Recodificar: preciso y seguro.
ffmpeg -i input.mp4 -ss 00:00:30 -t 15 -c:v libx264 -crf 20 -c:a aac out/clip.mp4
# Rápido, sin recodificar. Solo acierta en keyframes, por lo que el inicio puede desviarse por segundos.
ffmpeg -ss 00:00:30 -i input.mp4 -t 15 -c copy out/clip.mp4
-ss antes de -i busca rápido. Después de -i busca con precisión pero más lento. Para recodificaciones, ambos son válidos en FFmpeg moderno.
Unir
# Mismo códec, resolución, fps: instantáneo, sin pérdida
printf "file 'a.mp4'\nfile 'b.mp4'\n" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy out/joined.mp4
# Fuentes diferentes: normalizar al unir
ffmpeg -i a.mp4 -i b.mp4 -filter_complex \
"[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30,setsar=1[v0];\
[1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30,setsar=1[v1];\
[0:a][1:a]concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" -c:v libx264 -crf 20 -c:a aac out/joined.mp4
PowerShell: escribir list.txt con Set-Content, y usar continuación de línea con backtick o una línea larga en lugar de \.
Redimensionar y reencuadrar
# Ajustar dentro de 1920x1080 con barras
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2"
# Rellenar 1920x1080, recortar el exceso
-vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080"
# Ancho 1280, alto automático y par
-vf "scale=1280:-2"
Comprimir
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k -movflags +faststart out/small.mp4
| Propósito | CRF | Preset |
|---|---|---|
| Master / archivo | 16-18 | slow |
| Producción | 20-22 | medium |
| Web / vista previa | 23-26 | fast |
| Borrador rápido | 28+ | veryfast |
Un CRF más bajo significa mayor calidad y archivo más grande. Para un tamaño objetivo, usar -b:v en dos pasos en lugar de CRF.
Velocidad
# 2x más rápido, video y audio
ffmpeg -i in.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" out/fast.mp4
# 0.5x cámara lenta
ffmpeg -i in.mp4 -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" -map "[v]" -map "[a]" out/slow.mp4
# Solo video
ffmpeg -i in.mp4 -an -filter:v "setpts=0.25*PTS" out/timelapse.mp4
El multiplicador setpts = 1 / velocidad. atempo acepta 0.5 a 2.0 por filtro, así que encadenar para más: atempo=2.0,atempo=2.0 para 4x.
Fundidos
# 1 s de entrada, 1 s de salida en un clip de 10 s
ffmpeg -i in.mp4 -vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -af "afade=t=in:st=0:d=1,afade=t=out:st=9:d=1" out/faded.mp4
Audio
ffmpeg -i in.mp4 -vn -c:a libmp3lame -q:a 2 out/audio.mp3 # extraer mp3
ffmpeg -i in.mp4 -vn -c:a copy out/audio.m4a # extraer sin recodificar (fuente AAC)
ffmpeg -i video.mp4 -i voice.wav -map 0:v -map 1:a -c:v copy -c:a aac -shortest out/dubbed.mp4 # reemplazar audio
ffmpeg -i in.mp4 -an -c:v copy out/silent.mp4 # eliminar audio
GIF
ffmpeg -i in.mp4 -t 5 -vf "fps=15,scale=480:-1:flags=lanczos,split[a][b];[a]palettegen[p];[b][p]paletteuse" out/preview.gif
Imágenes
ffmpeg -ss 5 -i in.mp4 -frames:v 1 -q:v 2 out/frame.jpg # un fotograma
ffmpeg -framerate 30 -i frames/%04d.png -c:v libx264 -pix_fmt yuv420p out/from-frames.mp4
ffmpeg -loop 1 -i still.png -t 5 -c:v libx264 -pix_fmt yuv420p -r 30 out/still.mp4
Solución de problemas
| Síntoma | Solución |
|---|---|
height not divisible by 2 | Agregar scale=trunc(iw/2)*2:trunc(ih/2)*2 |
| Se reproduce en VLC, no en navegador o teléfono | -c:v libx264 -pix_fmt yuv420p -movflags +faststart |
| Audio se desincroniza después de cambio de velocidad | Usar setpts y atempo juntos en filter_complex |
| Audio se desincroniza en clips de teléfono con tasa de fotogramas variable | Agregar -vsync cfr -r 30 (o -fps_mode cfr) |
Primeros fotogramas negros después de recorte con -c copy | Recodificar en lugar de copiar el flujo |
| El archivo de salida tiene 0 bytes | Leer el error completo con -v error; verificar el mapeo de flujos |
| Rutas con espacios | Entrecomillarlas: "mi clip.mp4" |
| El aviso de sobrescritura bloquea la automatización | Agregar -y (sobrescribir) o -n (nunca) |
Hábitos de seguridad
- Escribir en
out/, nunca en la ruta de entrada. - Agregar
-hide_banner -loglevel erroren scripts,-statspara ver progreso. - Verificar el resultado con
ffprobey el skillvideo-qa.