No soy un gurú ffmpeg, pero esto debería funcionar.
En primer lugar, puede obtener el tamaño del video de entrada como este:
ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width in.mp4
Con un ffmpeg razonablemente reciente, puede cambiar el tamaño de su video con estas opciones:
ffmpeg -i in.mp4 -vf scale=720:480 out.mp4
Puede establecer el ancho o la altura -1
para permitir ffmpeg
cambiar el tamaño del video manteniendo la relación de aspecto. En realidad, -2
es una mejor opción ya que el valor calculado debería ser par. Entonces podrías escribir:
ffmpeg -i in.mp4 -vf scale=720:-2 out.mp4
Una vez que obtenga el video, puede ser más grande de lo esperado, 720x480
ya que deja ffmpeg
calcular la altura, por lo que tendrá que recortarlo. Esto se puede hacer así:
ffmpeg -i in.mp4 -filter:v "crop=in_w:480" out.mp4
Finalmente, podría escribir un script como este (se puede optimizar fácilmente, pero lo mantuve simple para la legibilidad):
#!/bin/bash
FILE="/tmp/test.mp4"
TMP="/tmp/tmp.mp4"
OUT="/tmp/out.mp4"
OUT_WIDTH=720
OUT_HEIGHT=480
# Get the size of input video:
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${FILE})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}
# Get the difference between actual and desired size
W_DIFF=$[ ${OUT_WIDTH} - ${IN_WIDTH} ]
H_DIFF=$[ ${OUT_HEIGHT} - ${IN_HEIGHT} ]
# Let's take the shorter side, so the video will be at least as big
# as the desired size:
CROP_SIDE="n"
if [ ${W_DIFF} -lt ${H_DIFF} ] ; then
SCALE="-2:${OUT_HEIGHT}"
CROP_SIDE="w"
else
SCALE="${OUT_WIDTH}:-2"
CROP_SIDE="h"
fi
# Then perform a first resizing
ffmpeg -i ${FILE} -vf scale=${SCALE} ${TMP}
# Now get the temporary video size
eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${TMP})
IN_WIDTH=${streams_stream_0_width}
IN_HEIGHT=${streams_stream_0_height}
# Calculate how much we should crop
if [ "z${CROP_SIDE}" = "zh" ] ; then
DIFF=$[ ${IN_HEIGHT} - ${OUT_HEIGHT} ]
CROP="in_w:in_h-${DIFF}"
elif [ "z${CROP_SIDE}" = "zw" ] ; then
DIFF=$[ ${IN_WIDTH} - ${OUT_WIDTH} ]
CROP="in_w-${DIFF}:in_h"
fi
# Then crop...
ffmpeg -i ${TMP} -filter:v "crop=${CROP}" ${OUT}