How to rotate a video 180° with FFmpeg?

I have a video that was rotated 180° when recorded. Is it possible to correct this with FFmpeg?


originalrotated


tl;dr

ffmpeg will automatically rotate the video unless:

  • your input contains no rotate metadata
  • your ffmpeg is too old

Rotation metadata

Some videos, such as from iPhones, are not physically flipped, but contain video stream displaymatrix side data or rotate metadata. Some players ignore these metadata and some do not. Refer to ffmpeg console output to see if your input has such metadata:

$ ffmpeg -i input.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Duration: 00:00:05.00, start: 0.000000, bitrate: 43 kb/s
    Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 39 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      rotate          : 180
    Side data:
      displaymatrix: rotation of -180.00 degrees

Autorotation

ffmpeg will automatically physically rotate the video according to any existing video stream rotation metadata.

You need a build that includes commit 1630224, from 2 May 2015, to be able to use the autorotation feature.

Example

ffmpeg -i input.mp4 -c:a copy output.mp4

To disable this behavior use the -noautorotate option.


If the input contains no metadata or if your ffmpeg is old

You will have to use a filter to rotate the video, and if any rotate metadata exists it will have to be removed as shown in the examples below:

Examples

Using ffmpeg you have a choice of three methods of using video filters to rotate 180°.

hflip and vflip

ffmpeg -i input.mp4 -vf "hflip,vflip,format=yuv420p" -metadata:s:v rotate=0 \
-codec:v libx264 -codec:a copy output.mkv

transpose

ffmpeg -i input.mp4 -vf "transpose=2,transpose=2,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

rotate

This filter can rotate to any arbitrary angle and uses radians as a unit instead of degrees. This example will rotate π/1 radians, or 180°:

ffmpeg -i input.mp4 -vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

You can use degrees instead. One degree is equal to π/180 radians. So if you want to rotate 45°:

ffmpeg -i input.mp4 -vf "rotate=45*(PI/180),format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

When using the rotate filter, the bilinear interpolation should be turned off (by using bilinear=0) for angles divisible by 90, otherwise it may look blurry.


Notes

  • Filtering requires encoding. These examples make H.264 video outputs. See the FFmpeg H.264 Video Encoding Guide for guidance on getting the quality you want.

  • Chroma subsampling. I included format=yuv420p since ffmpeg will attempt to minimize or avoid chroma subsampling (depending on the encoder, input, ffmpeg version, etc). This is good behavior in a purely technical sense, but most players are incompatible with more "advanced" chroma subsampling schemes. This is the same as using -pix_fmt yuv420, but is conveniently located in the filterchain.

  • Copy the audio. The -codec:a copy option will stream copy (re-mux) instead of encode. There is no reason to re-encode the audio if you just want to manipulate the video only (unless you want to convert to a different audio format). This will save time since encoding is time consuming and it will preserve the quality of the audio.


Rotate upon playback

Alternatively you can rotate upon playback and avoid re-encoding. ffplay will automatically rotate:

ffplay input.mp4

If there is no displaymatrix side data or rotate metadata then you can use filters:

ffplay -vf "hflip,vflip" -i input.mp4

...or refer to your favorite player. Most players worth using, like VLC, have this capability.


Getting ffmpeg

Older builds of ffmpeg do not include filtering capabilities. See the FFmpeg download page for several options including convenient builds for Linux, OS X, and Windows, or refer to the FFmpeg Wiki for step-by-step ffmpeg compile guides.


FFMPEG changed the default behavior to auto rotate input video sources with "rotate" metadata in the v2.7 release in 2015.

If you know your script or command will never run on ffmpeg releases older than 2.7, the simplest solution is to remove any custom rotation based on metadata.

For other cases you can future-proof by keeping your custom rotation code and adding the -noautorotate flag (this is supported in older versions which were still maintained at the time).


Media players that use ffmpeg as a decoding backend can also utilize all of its filters. See this screenshot with "Offset & flip" filter. enter image description here

Alternatively, if you want to re-encode your video, check out Rotating videos with FFmpeg on Stackoverflow.