Traté de resolver esto por mí mismo, pero la gran cantidad de opciones me desconcierta.
Quiero usar idealmente ffmpeg
o mencoder
(o algo más, pero esos dos que sé que tengo funcionando) para convertir cualquier video entrante a un tamaño de pantalla fijo.
Si el video es más ancho o demasiado corto, recorta el video al centro. Si no tiene el tamaño correcto, cambie el tamaño hacia arriba o hacia abajo para que sea exactamente el tamaño de pantalla fijo.
Lo último que necesito exactamente es 720 × 480 en un AVI XVid con una pista de audio MP3.
Encontré muchas páginas que muestran cómo cambiar el tamaño a una resolución máxima, pero necesito que el video tenga exactamente esa resolución (con partes adicionales recortadas, sin barras negras).
¿Alguien puede decirme la línea de comando para ejecutar, o al menos ayudarme un poco o la mayor parte del camino? Si necesita varias líneas de comando (ejecutar X para obtener la resolución, hacer este cálculo y luego ejecutar Y con el resultado de ese cálculo) puedo programar eso.
Respuesta aceptada:
No soy un gurú de ffmpeg, pero esto debería funcionar.
En primer lugar, puede obtener el tamaño del video de entrada de esta manera:
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 en -1
para permitir que 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. Así que 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
desde que dejaste ffmpeg
calcule la altura, por lo que tendrá que recortarla. 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 que sea legible):
#!/bin/bash
FILE="//eadn-wc01-5196795.nxedge.io/tmp/test.mp4"
TMP="//eadn-wc01-5196795.nxedge.io/tmp/tmp.mp4"
OUT="//eadn-wc01-5196795.nxedge.io/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}