Rotación de videos con FFmpeg

417

He estado tratando de descubrir cómo rotar videos con FFmpeg. Estoy trabajando con videos de iPhone tomados en modo vertical. Sé cómo determinar los grados de rotación actuales 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 ya no existe, ahora es solo -vf . En segundo lugar, me sale este error:

No such filter: 'rotate'
Error opening filters!

Hasta donde sé, tengo una compilación de FFmpeg con todas las opciones. Ejecutar ffmpeg -filters 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 son geniales y todo, pero simplemente no me llevarán a donde necesito ir. Necesito la capacidad de rotar videos 90 grados como mínimo. 270 grados sería una excelente opción para tener también. ¿Dónde se han ido las opciones de rotación?

jocull
fuente
77
Para cualquiera que -vf "vflip,hflip"
busque
44
Me pregunto si esto se puede lograr sin decodificar y luego volver a codificar el video, la forma en que jpegtran puede girar sin pérdida de imágenes JPEG ...
Mikhail T.
2
Vea aquí la bandera de rotación: stackoverflow.com/questions/15335073/…
Davor Josipovic el
1
También vea la respuesta detallada en Cómo voltear un video 180 ° (vertical / invertido) con FFmpeg? No olvide restablecer los metadatos de rotación existentes (vea el enlace).
llogan
1
Acabo de subir un video girado 180 ° con "transpose = 1, transpose = 1" a vimeo. Aunque puedo reproducir el video girado, fue rechazado por vimeo. El enfoque de @ OrangeDog funciona a las mil maravillas -vf "vflip,hflip".
Besi

Respuestas:

683

Gire 90 en sentido horario:

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

Para el parámetro de transposición puede pasar:

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

Usar -vf "transpose=2,transpose=2"por 180 grados.

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

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

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

Alexy
fuente
8
El video seguirá teniendo la información de orientación, por lo que ahora el video se corregirá en el iPhone.
srcspider
26
Cuando utilizo este comando, aparece un salida de vídeo de baja calidad , a menos que - como he acabo de descubrir - Yo uso este parámetro, así: -vcodec libx264. Pero sería genial si no tuviera que buscar qué codificación usar como ffmpeg ya debería saberlo. ¿Alguna sugerencia?
Sadi
8
En la misma línea que Sadi, ¿hay alguna forma de "copiar" la calidad del video original?
Alec Jacobson el
58
Por 180 puedes usar-vf "transpose=2,transpose=2"
Alex Pliutau
23
Los documentos actuales señalan que "los valores numéricos están en desuso y deben descartarse a favor de las constantes simbólicas". ffmpeg.org/ffmpeg-filters.html#transpose Por lo tanto cclock_flip, clock, cclocko clock_flipen lugar de 0, 1, 2o 3.
l --mar l l
149

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

ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v
Rodrigo Polo
fuente
11
¿qué hay de comprobar los metadatos de rotación primero conffmpeg -i input.m4v 2>&1 | grep rotate
lidaobing
6060
Esta es la mejor respuesta con diferencia. Pero hay una pequeña mejora que hacer. Para evitar perder los metadatos restantes (como la fecha, la cámara) en el video, hazlo ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v. De esta forma, todos los metadatos globales del archivo de entrada se copiarán como metadatos globales al archivo de salida y solo se cambiarán los metadatos de rotación.
migle
11
Si tiene un video en modo retrato y solo quiere "rotarlo UN" para tener un 1920x1080 estándar, entonces probablemente lo desee rotate=0.
mivk
1
Probado -metadata:s:v rotate="180", no funcionó. ¿Se supone que eso funciona?
Ondra Žižka
77
La mejor solución en mi humilde opinión porque no es necesario volver a codificar y la mayoría de los reproductores de video admiten la rotación de metadatos. También servicios en la nube como Google Photos. Sin embargo, recuerde que ffmpeg no necesariamente copia todos los metadatos del archivo original. Por lo tanto, recomiendo que especificar explícitamente para copiar todos los otros metadatos del archivo original:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
Andreas
83

¿Ya lo has intentado transpose? Me gusta (de la otra respuesta)

 ffmpeg -i input -vf transpose=2 output

Si está utilizando una versión anterior, debe actualizar ffmpeg si desea utilizar la función de transposición, 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.

rwilliams
fuente
1
No, no tengo. No sabía que existía. Le daré una oportunidad.
jocull
El filtro de transposición no parece existir en ninguna de mis compilaciones de FFmpeg. ¿Cómo se supone que debo agregarlo?
Jocull
En la versión de los documentos a partir del 2011-05-15, el enlace correcto ahora es ffmpeg.org/ffmpeg-doc.html#SEC93
Peter Hansen
66
Parece que me castigaron por ofrecer una respuesta útil 1.5 años antes de la respuesta aceptada.
rwilliams
1
@JonasB Separe los filtros con comas. Ver stackoverflow.com/questions/6195872/…
rwilliams
19

Encontré esta página mientras buscaba la misma respuesta. Han pasado seis meses desde que esto se solicitó originalmente y las compilaciones 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 la versión Debian Squeeze y FFmpeg de esos repositorios.

La página MAN para ffmpeg establece el siguiente uso

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

La clave es que no debe utilizar una variable de grado, sino una variable de configuración predefinida de la página MAN.

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip
Zonjai
fuente
Gracias por la info! Nunca pude lograr que esto funcionara, ya que generalmente tengo problemas para construir desde la fuente. Puedo ver si puedo hacerlo funcionar de nuevo ahora.
jocull
transponer = 3 está causando que la imagen se refleje
Daniel Kobe
transpuesta = 2 trabajaron sin reflejo de mi vídeo girada 270
Daniel Kobe
17

Para rotar la imagen en el sentido de las agujas del reloj, puede usar el filtro de rotación, que indica un ángulo positivo en radianes. Con 90 grados equivalentes a PI / 2, puede hacerlo así:

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

en sentido antihorario, el ángulo debe ser negativo

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

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

Bijou Trouvaille
fuente
2
esto es genial. Descubrí que es posible obtener una resolución más fina de los radianes, porque se *comporta como una multiplicación: ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi (un poco menos de rotación que -PI / 4 = -10 * PI / 40)
eqzx
12
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

nano
fuente
eso es porque estás aplicando el filtro al archivo incorrecto ... prueba ffmpeg -i input.mp4 -vf "rotate = 90" output.mp4, entonces funcionará
patrick
2
"Rotar el video en un ángulo arbitrario expresado en radianes ". Documentación: ffmpeg.org/ffmpeg-filters.html#rotate Entonces, radianes rotate=PI/2o rotate=90*PI/180es necesario
l --marc l
Esto es fantástico
Tessaracter
7

Si obtiene el error "El códec es experimental pero los códecs experimentales no están habilitados" use esto:

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

Pasó conmigo por algún archivo .mov con audio aac.

sabujp
fuente
Este fue el único ejemplo que funcionó para mí, pero la calidad era terrible y muy compleja. Además, redujo un video de 1080x1920 a 352x640. Supongo que me falta uno o dos interruptores. ¿Alguna sugerencia?
LOlliffe
1
@LOlliffe add-sameq
Andrew Schleifer
2
@AndrewSchleifer Gracias. Lo intenté, pero ffmpeg me arrojó Option 'sameq' was removed. If you are looking for an option to preserve the quality (which is not what -sameq was for), use -qscale 0 or an equivalent quality factor option. Failed to set value '1' for option 'sameq': Invalid argument -qscale también da un error. Please use -q:a or -q:v, -qscale is ambiguous, pero aún funciona.
LOlliffe
3

Este script que generará los archivos con la estructura de directorios en "fixedFiles". Por el momento está fijado a archivos MOV y ejecutará una serie de transformaciones dependiendo de la "rotación" original del video. Funciona con videos capturados de iOS en una Mac con Mavericks, pero debe ser fácilmente exportable. Se basa en haber 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
David Costa Faidella
fuente
2
Ay ... Esto puede funcionar, pero es perfectamente horrible. En primer lugar, la regla general de la programación de shell: nunca necesita más de grep, cut, awk o sed en una tubería. Cualquier grep | cut | sed es factible con sed o awk solo. Luego, más específicamente, se le puede pedir a exiftool que muestre solo la (s) etiqueta (s) que desee, por lo que en lugar de filtrar la rotación, simplemente "exiftool -Rotation". En tercer lugar, no necesita tantos "evals" y su "prueba if ..." debe reemplazarse con el caso $ ROTATION in, tanto para la legibilidad como para la eficiencia. ¡Buena suerte!
Mikhail T.
Sin dados: [Parsed_pad_2 @ 0x7f8b15c3a580] Input area -420:0:1500:1080 not within the padded area 0:0:1080:1080 or zero-sized\ n ` [Parsed_pad_2 @ 0x7f8b15c3a580] Failed to configure input pad on Parsed_pad_2\ n Error reinitializing filters!\ n Failed to inject frame into filter network: Invalid argument\ n Error while processing the decoded data for stream #0:0\ nConversion failed!
Slipp D. Thompson
2

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

base de tiempo 1/90000 no compatible con el estándar MPEG 4, el valor máximo admitido para el denominador de base de tiempo es 65535

Simplemente tuve que agregar un parámetro (-r 65535/2733) al comando y funcionó. El comando completo era así:

ffmpeg -i in.mp4 -vf "transpose=1" -r 65535/2733 out.mp4
smoyth
fuente
Si está buscando una velocidad de fotogramas de "película NTSC", entonces 24000/1001sería más preciso.
Reino
2

Una solución adicional con un enfoque diferente de las últimas soluciones mencionadas es verificar si el controlador de su cámara admite los controles de la cámara v4l2 (que es muy común).
En la terminal solo escribe:

v4l2-ctl -L

Si el controlador de su cámara admite los controles de la cámara v4l2, debería obtener algo como esto (la lista a continuación depende de los controles que admite el controlador de la cámara):

               contrast (int)    : min=0 max=255 step=1 default=0 value=0 flags=slider
             saturation (int)    : min=0 max=255 step=1 default=64 value=64 flags=slider
                    hue (int)    : min=0 max=359 step=1 default=0 value=0 flags=slider
white_balance_automatic (bool)   : default=1 value=1 flags=update
            red_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
           blue_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
               exposure (int)    : min=0 max=65535 step=1 default=0 value=885 flags=inactive, volatile
         gain_automatic (bool)   : default=1 value=1 flags=update
                   gain (int)    : min=0 max=1023 step=1 default=0 value=32 flags=inactive, volatile
        horizontal_flip (bool)   : default=0 value=0
          vertical_flip (bool)   : default=0 value=0

Y si tienes suerte, admite horizontal_flip y vertical_flip .
Entonces todo lo que necesita hacer es establecer el horizontal_flip por:

v4l2-ctl --set-ctrl horizontal_flip=1

o el vertical_flip por:

v4l2-ctl --set-ctrl vertical_flip=1

y luego puede llamar a su dispositivo de video para capturar un video nuevo (vea el ejemplo a continuación), y el video se rotará / volteará.

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -vcodec libx264 -f mpegts input.mp4

Por supuesto, si necesita procesar un video ya existente, entonces este método no es la solución que está buscando.

La ventaja de este enfoque es que volteamos la imagen en el nivel del sensor, por lo que el sensor del controlador ya nos da la imagen invertida, y eso ahorra a la aplicación (como FFmpeg) cualquier procesamiento adicional e innecesario.

JM
fuente
Gran información sobre v4l2 aquí. Obviamente, es preferible rotar a la orientación correcta en el momento de la grabación :) Esta pregunta de casi 10 años (¡guau!) Se hizo originalmente sobre los videos que se cargan desde dispositivos iOS si eso ayuda a proporcionar algún contexto :)
Jocull
Soy un poco nuevo en esta comunidad y esta pregunta es mucho más antigua que mi antigüedad aquí ... Realmente creo que es una buena (y común) pregunta, así que creo que esta vieja pregunta seguirá ayudando a muchos usuarios de FFmpeg.
JM
1

Desafortunadamente, la versión de Ubuntu de ffmpeg admite videofiltros.

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

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

ldig
fuente
1
¿Quiso decir "la versión de Ubuntu de ffmpeg no admite videofiltros"?
user1438038
2
FYI: "FFmpeg ha regresado en Ubuntu 15.04 Vivid Vervet". o se puede compilar para Ubuntu. -> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l
avconv lo hace (en 14.04), y parece funcionar exactamente igual. (Pero para versiones posteriores, definitivamente use FFmpeg.)
SilverWolf - Reinstale Monica el
1

Smartphone: recuperó un video en formato vertical

Desea enviarlo a un lado web que estaba 90 ° a la izquierda (en sentido antihorario, formato horizontal) hmm.

ffmpeg -i input.mp4 -vf "rotate=0" output.mp4

lo hace. Tengo formato vertical de nuevo

debian buster: ffmpeg --version ffmpeg versión 4.1.4-1 ~ deb10u1 Copyright (c) 2000-2019 los desarrolladores de FFmpeg

pensión completa
fuente