Rotación de vídeos con FFmpeg


He estado tratando de averiguar cómo rotar videos con FFmpeg. Estoy trabajando con videos de iPhone tomados en modo retrato. Sé cómo determinar los grados actuales de rotación usando MediaInfo (excelente biblioteca, por cierto) pero ahora estoy atascado en FFmpeg.

Por lo que he leído, lo que necesita usar es una opción vfilter. Según lo que veo, debería verse así:

ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4

Sin embargo, no puedo hacer que esto funcione. Primero, - vfilters no existe más, ahora es solo -vf. Segundo, obtengo este error:

No such filter: 'rotate'
Error opening filters!

Por lo que sé, tengo una compilación de todas las opciones de FFmpeg. Corriendo ffmpeg-filtros muestra esto:

Filters:
anull            Pass the source unchanged to the output.
aspect           Set the frame aspect ratio.
crop             Crop the input video to x:y:width:height.
fifo             Buffer input images and send them when they are requested.
format           Convert the input video to one of the specified pixel formats.
hflip            Horizontally flip the input video.
noformat         Force libavfilter not to use any of the specified pixel formats
 for the input to the next filter.
null             Pass the source unchanged to the output.
pad              Pad input image to width:height[:x:y[:color]] (default x and y:
 0, default color: black).
pixdesctest      Test pixel format definitions.
pixelaspect      Set the pixel aspect ratio.
scale            Scale the input video to width:height size and/or convert the i
mage format.
slicify          Pass the images of input video on to next video filter as multi
ple slices.
unsharp          Sharpen or blur the input video.
vflip            Flip the input video vertically.
buffer           Buffer video frames, and make them accessible to the filterchai
n.
color            Provide an uniformly colored input, syntax is: [color[:size[:ra
te]]]
nullsrc          Null video source, never return images.
nullsink         Do absolutely nothing with the input video.

Tener las opciones para vflip y hflip es genial y todo, pero simplemente no me donde tengo que ir. Necesito la capacidad de rotar videos 90 grados como mínimo. 270 grados sería una excelente opción para tener también. Donde tienen la rotación las opciones ido?

Author: Michael Currie, 2010-10-15

10 answers

Gire 90 en el sentido de las agujas del reloj:

ffmpeg -i in.mov -vf "transpose=1" out.mov

Para el parámetro transpose puede pasar:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Use -vf "transpose=2,transpose=2" para 180 grados.

Asegúrese de usar una versión reciente de ffmpeg desde aquí (una compilación estática funcionará bien).

Tenga en cuenta que esto re-codificará las partes de audio y vídeo. Por lo general, puede copiar el audio sin tocarlo, utilizando -c:a copy. Para cambiar la calidad del vídeo, establezca la tasa de bits (por ejemplo con -b:v 1M) o eche un vistazo a la codificación H. 264 guía si quieres opciones de VBR.

Una solución es también usar este script de conveniencia .

 506
Author: Alexy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-19 11:52:43

¿Has intentado transpose ¿todavía? Como (de la otra respuesta)

 ffmpeg -i input -vf transpose=2 output

Si está utilizando una versión antigua, debe actualizar ffmpeg si desea utilizar la función transponer, como se agregó en octubre de 2011.

La página de descarga de FFmpeg ofrece compilaciones estáticas que puede ejecutar directamente sin tener que compilarlas.

 76
Author: rwilliams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-19 11:55:30

Si no desea volver a codificar su video y su reproductor puede manejar los metadatos de rotación, puede cambiar la rotación en los metadatos usando ffmpeg:

ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v
 73
Author: Rodrigo Polo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-28 18:05:43

Me encontré con esta página mientras buscaba la misma respuesta. Han pasado seis meses desde que esto se pidió originalmente y las versiones se han actualizado muchas veces desde entonces. Sin embargo, quería agregar una respuesta para cualquier otra persona que se encuentre aquí buscando esta información.

Estoy usando Debian Squeeze y FFmpeg versión de esos repositorios.

La página de MANUAL para ffmpeg indica el siguiente uso

ffmpeg -i inputfile.mpg -vf "transpose=1" outputfile.mpg

La clave es que no debes usar un título variable, pero una variable de configuración predefinida de la página de manual.

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip
 16
Author: Zonjai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-02 00:45:36
ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4 

No funcionará, incluso con la última fuente...

Debe cambiar el orden:

ffmpeg -i input.mp4 -vf vflip output.mp4

Funciona bien

 11
Author: nano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-16 02:27:31

Para rotar la imagen en el sentido de las agujas del reloj puede utilizar el filtro rotar, que indica un ángulo positivo en radianes. Con 90 grados igualando con PI/2, puedes hacerlo así:

ffmpeg -i in.mp4 -vf "rotate=PI/2" out.mp4

Para el sentido contrario a las agujas del reloj el ángulo debe ser negativo

ffmpeg -i in.mp4 -vf "rotate=-PI/2" out.mp4

El filtro de transposición funcionará igualmente bien para 90 grados, pero para otros ángulos esta es una opción más rápida o única.

 11
Author: Bijou Trouvaille,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-11 06:05:20

Si está obteniendo un error "Codec is experimental but experimental codecs are not enabled" use esto:

ffmpeg -i inputFile -vf "transpose=1" -c:a copy outputFile

Pasó conmigo para algunos .archivo mov con audio aac.

 6
Author: sabujp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-04 21:50:39

Este script que generará los archivos con la estructura de directorios bajo "fixedFiles". Por el momento se fija a los archivos MOV y ejecutará una serie de transformaciones en función de la "rotación" original del vídeo. Funciona con videos capturados de iOS en un Mac que ejecuta Mavericks, pero debe ser fácilmente exportable. Se basa en tener instalado exiftool y ffmpeg.

#!/bin/bash

# rotation of 90 degrees. Will have to concatenate.
#ffmpeg -i <originalfile> -metadata:s:v:0 rotate=0 -vf "transpose=1" <destinationfile>
#/VLC -I dummy -vvv <originalfile> --sout='#transcode{width=1280,vcodec=mp4v,vb=16384,vfilter={canvas{width=1280,height=1280}:rotate{angle=-90}}}:std{access=file,mux=mp4,dst=<outputfile>}\' vlc://quit

#Allowing blanks in file names
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

#Bit Rate
BR=16384

#where to store fixed files
FIXED_FILES_DIR="fixedFiles"
#rm -rf $FIXED_FILES_DIR
mkdir $FIXED_FILES_DIR

# VLC
VLC_START="/Applications/VLC.app/Contents/MacOS/VLC -I dummy -vvv"
VLC_END="vlc://quit"


#############################################
# Processing of MOV in the wrong orientation
for f in `find . -regex '\./.*\.MOV'` 
do
  ROTATION=`exiftool "$f" |grep Rotation|cut -c 35-38`
  SHORT_DIMENSION=`exiftool "$f" |grep "Image Size"|cut -c 39-43|sed 's/x//'`
  BITRATE_INT=`exiftool "$f" |grep "Avg Bitrate"|cut -c 35-38|sed 's/\..*//'`
  echo Short dimension [$SHORT_DIMENSION] $BITRATE_INT

  if test "$ROTATION" != ""; then
    DEST=$(dirname ${f})
    echo "Processing $f with rotation $ROTATION in directory $DEST"
    mkdir -p $FIXED_FILES_DIR/"$DEST"

    if test "$ROTATION" == "0"; then
      cp "$f" "$FIXED_FILES_DIR/$f"

    elif test "$ROTATION" == "180"; then
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{vfilter={rotate{angle=-"$ROTATION"}},vcodec=mp4v,vb=$BR}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      $(eval ffmpeg -i \"$f\" -vf hflip,vflip -r 30 -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\")

    elif test "$ROTATION" == "270"; then
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=2,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    else
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{scale=1,width=$SHORT_DIMENSION,vcodec=mp4v,vb=$BR,vfilter={canvas{width=$SHORT_DIMENSION,height=$SHORT_DIMENSION}:rotate{angle=-"$ROTATION"}}}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      echo ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" 
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    fi

  fi

echo 
echo ==================================================================
sleep 1
done

#############################################
# Processing of AVI files for my Panasonic TV
# Use ffmpegX + QuickBatch. Bitrate at 16384. Camera res 640x424
for f in `find . -regex '\./.*\.AVI'` 
do
  DEST=$(dirname ${f})
  DEST_FILE=`echo "$f" | sed 's/.AVI/.MOV/'`
  mkdir -p $FIXED_FILES_DIR/"$DEST"
  echo "Processing $f in directory $DEST"
  $(eval ffmpeg -i \"$f\" -r 20 -acodec libvo_aacenc -b:a 128k -vcodec mpeg4 -b:v 8M -flags +aic+mv4 \"$FIXED_FILES_DIR/$DEST_FILE\" )
echo 
echo ==================================================================

done

IFS=$SAVEIFS
 3
Author: David Costa Faidella,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-04 23:59:39

La respuesta de Alexy casi funcionó para mí, excepto que estaba recibiendo este error:

Timebase 1/90000 no soportado por el estándar MPEG 4, el máximo el valor admitido para el denominador de la base de tiempo es 65535

Solo tuve que añadir un parámetro (-r 65535/2733) al comando y funcionó. La orden completa era así:

ffmpeg -i in.mp4 -vf "transpose=1" -r 65535/2733 out.mp4
 2
Author: smoyth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-19 19:48:59

Desafortunadamente, la versión Ubuntu de ffmpeg soporta videofilters.

Necesita usar avidemux o algún otro editor para lograr el mismo efecto.

En la forma programática, se ha recomendado mencoder.

 1
Author: ldig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-24 22:14:04