Cómo cambiar el tamaño de un vídeo con ffmpeg
Para cambiar el tamaño de un vídeo con el filtro de vídeo scale:
ffmpeg -i video.mp4 -vf scale=${anchura}:${altura} video_escalado.mp4
Vamos a tomar como referencia un vídeo de 1920×1080:
$ ffmpeg -i video.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1920x1080 [SAR 1:1 DAR 16:9], 1040 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Modificar la anchura y altura de un vídeo
Para cambiar su tamaño a una resolución especificada en anchura y altura tenemos varias opciones.
La forma más simple es con el modificador -s e indicándole ${anchura}x${altura}. Aquí la separación entre la anchura y la altura es mediante una x:
ffmpeg -i video.mp4 -s 1280x720 video_s_1280_720.mp4
Si sabemos la anchura y la altura del vídeo a generar, lo realiza sin problemas.
$ ffmpeg -i video_s_1280_720.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 610 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Otra opción es con el filtro de vídeo scale, al cual podemos invocar con -filter:v scale o con -vf scale:
ffmpeg -i video.mp4 -filter:v scale=1280:720 video_filter_v_1280_720.mp4 ffmpeg -i video.mp4 -vf scale=1280:720 video_1280_720.mp4
Que también realiza el cambio sin ningún problema:
$ ffmpeg -i video_filter_v_1280_720.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 610 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) $ ffmpeg -i video_1280_720.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 610 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
No necesariamente tenemos que indicar la misma proporción para anchura y altura. Vamos a ver qué pasa si le cambiamos el tamaño de forma desproporcionada:
ffmpeg -i video.mp4 -vf scale=1980:720 video_1980_720.mp4
Genera un vídeo con ese tamaño:
$ ffmpeg -i video_1980_720.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1980x720 [SAR 64:99 DAR 16:9], 826 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Modificar sólo anchura o altura
Hasta ahora, hemos pasado dos valores a scale, por lo que tendríamos que haber calculado previamente esos dos valores. La mayoría de las veces partimos de uno solo. Podemos calcularlo previamente o indicarle a ffmpeg que lo calcule con:
-vf scale=${anchura}:-1 -vf scale=-1:${altura}
Antes de hacerlo, vamos a ver dos errores que podemos cometer.
1.- Indicar sólo la anchura o la altura, sin dos puntos ni menos uno:
ffmpeg -i video.mp4 -vf scale=1280 video_1280.mp4
2.- Escribir los dos puntos, pero no el menos uno:
ffmpeg -i video.mp4 -vf scale=1280: video_1280_.mp4
Cualquiera de las dos opciones nos generará un fichero vacío.
$ ls -sh video_1280.mp4 0 video_1280.mp4 $ ls -sh video_1280_.mp4 0 video_1280_.mp4
Por lo que tendremos que tener cuidado y escribir correctamente el comando, ya que el hecho de que genere el fichero puede dar lugar a confusión.
Hecha esta aclaración, veamos cómo generar un nuevo vídeo con la anchura y la altura proporcionadas:
ffmpeg -i video.mp4 -vf scale=1280:-1 video_1280-1.mp4 ffmpeg -i video.mp4 -vf scale=-1:720 video_-1_720.mp4
Que, en ambas ocasiones, nos genera el resultado esperado:
$ ffmpeg -i video_1280-1.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 610 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) $ ffmpeg -i video_-1_720.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 610 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Asegurar la desproporción
Según el sistema, ffmpeg puede estar compilado de una u otra manera. Para garantizar que podamos indicarle una anchura y una altura y nos respete los nuevos valores dados, podemos forzar a ffmpeg con setsar=1:
ffmpeg -i video.mp4 -vf scale=1920:200,setsar=1 video_1920_200.mp4
Nos devolverá el resultado esperado independientemente de la compilación de ffmpeg que tengamos.
$ ffmpeg -i video_1920_200.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 1920x200 [SAR 1:1 DAR 48:5], 287 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Modificar en relación a la altura o la anchura
Podemos también indicarle a ffmpeg que realice la operación de calcular la nueva altura o anchura operando con iw y con ih:
ffmpeg -i video.mp4 -vf scale="iw/2:ih/2" video_mitad.mp4 ffmpeg -i video.mp4 -vf scale="iw*2:ih*2" video_doble.mp4
Y podemos comprobar que realiza correctamente la acción con:
$ ffmpeg -i video_mitad.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 960x540 [SAR 1:1 DAR 16:9], 414 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) $ ffmpeg -i video_doble.mp4 2>&1 > /dev/null | grep "Stream #0:0" Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown), 3840x2160 [SAR 1:1 DAR 16:9], 2949 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)