FFMPEG COMMAND

Rotate a video with FFmpeg

Two kinds of rotation exist. transpose really rotates the pixels and re-encodes; -display_rotation only writes a display matrix the player applies, which is instant with stream copy. FFmpeg 9 also applies an existing rotation flag by itself when it re-encodes, which surprises people.

Verified with FFmpeg 9.0.1 on 26 August 2026. Search intent: ffmpeg rotate video.

the command
ffmpeg -i input.mp4 -vf "transpose=1" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4

Rotates every frame 90 degrees clockwise and re-encodes. The 1280x720 test file became a real 720x1280 file with no rotation metadata, so every player shows it the same way. Audio is copied.

Flags, explained

transpose=1
90 degrees clockwise. 2 is counter-clockwise, 0 and 3 combine a rotation with a vertical flip.
hflip,vflip
Mirror horizontally then vertically, which equals a 180 degree rotation.
-display_rotation 90
Input option (before -i): set the display matrix of the video stream to 90 degrees counter-clockwise. Negative values rotate clockwise; 0 clears an existing flag.
-c copy
Copy the streams. Only valid with the metadata approach, since transpose changes pixels.
-noautorotate
Do not apply the display matrix of the input while decoding.

Variants

90 degrees counter-clockwise

shell
ffmpeg -i input.mp4 -vf "transpose=2" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4

transpose=2 turns the picture the other way. Same 720x1280 output size.

180 degrees

shell
ffmpeg -i input.mp4 -vf "transpose=1,transpose=1" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4

Two clockwise quarter turns. hflip,vflip gives the identical result (same 4,503,046-byte file here) and reads more clearly.

Metadata-only rotation, no re-encode

shell
ffmpeg -display_rotation 90 -i input.mp4 -c copy rotated.mp4

Writes a display matrix and copies the streams: the file stays 1280x720 inside, ffprobe reports rotation 90 as side data, and players that honour the matrix (all modern ones) show it counter-clockwise. Took a fraction of a second, same size as the input. Use -display_rotation -90 for clockwise.

Remove a rotation flag from a phone video (bake it in)

shell
ffmpeg -i phone.mp4 -c:v libx264 -crf 23 -preset medium -c:a copy fixed.mp4

No filter needed: FFmpeg 9 applies the display matrix while decoding, so a 1280x720 file flagged 90 degrees comes out as a real 720x1280 file with the flag cleared. This is the fix for players and pipelines that ignore the flag.

Keep the flag instead of applying it

shell
ffmpeg -noautorotate -i phone.mp4 -c:v libx264 -crf 23 -preset medium -c:a copy reencoded.mp4

With -noautorotate the pixels stay 1280x720 and the rotation 90 side data is carried over. Only useful when a later step expects the flag.

Pitfalls we hit

  • The old trick -metadata:s:v:0 rotate=90 does nothing in FFmpeg 9: the output had no rotation side data at all. Use -display_rotation.
  • transpose does not take 180 as an argument; chain two transposes or use hflip,vflip.
  • Re-encoding a phone video applies its rotation flag automatically. If your pipeline then adds transpose=1 on top, the result is rotated twice.
  • A metadata-only rotation is invisible to players and tools that ignore the display matrix (some older web players, thumbnailers, ML pipelines). When it must be right everywhere, bake it in with a re-encode.
  • Positive -display_rotation is counter-clockwise, the opposite of what many people expect from "rotate 90".

How we verified it

Run with FFmpeg 9.0.1 on 26 August 2026 against a 12 s, 1280x720 H.264/AAC file. transpose=1: 720x1280, 360 frames, 4,353,329 bytes. transpose=2: 720x1280, 4,485,894 bytes. transpose=1,transpose=1 and hflip,vflip: both 1280x720, 4,503,046 bytes. -display_rotation 90 with -c copy: 1280x720 stored, side data rotation 90, 4,896,094 bytes (input size). -metadata:s:v:0 rotate=90 with -c copy: no rotation side data written. Re-encoding the flagged file: 720x1280 and the flag cleared (4,485,894 bytes, the transpose=2 result). With -noautorotate: 1280x720, rotation 90 kept. -display_rotation 0 with -c copy cleared the flag.

The same edit as a typed operation

auto_orient_video reads the rotation flag of a phone recording and bakes it into the pixels, returning an upright MP4 with no metadata for other tools to misread. The probe, the decision and the encode happen in one job.

MCP tool: auto_orient_videoPOST /api/v1/tools/auto-orient-video
request body
{
  "inputs": [{ "id": "main", "url": "https://example.com/phone-video.mov" }]
}

FAQ

How do I rotate a video 90 degrees with FFmpeg?

Use -vf transpose=1 for clockwise or transpose=2 for counter-clockwise and re-encode the video. The output dimensions swap, 1280x720 becomes 720x1280, and no player needs to interpret anything.

Can I rotate a video without re-encoding?

Yes, by changing the display matrix: ffmpeg -display_rotation 90 -i in.mp4 -c copy out.mp4. The pixels are untouched and the file keeps its size, but only players that honour the flag show it rotated.

Why is my phone video sideways after FFmpeg processing?

Either the flag was applied twice (FFmpeg autorotated and you added transpose) or your player ignores the display matrix. Re-encode once without a transpose filter: FFmpeg 9 bakes the rotation in and clears the flag.

Why does -metadata rotate=90 not work anymore?

FFmpeg stopped honouring the rotate tag as a way to set orientation; in our test the output had no rotation side data. The supported option is -display_rotation, placed before -i.

Related commands

All FFmpeg commands