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.
ffmpeg -i input.mp4 -vf "transpose=1" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4Rotates 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
ffmpeg -i input.mp4 -vf "transpose=2" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4transpose=2 turns the picture the other way. Same 720x1280 output size.
180 degrees
ffmpeg -i input.mp4 -vf "transpose=1,transpose=1" -c:v libx264 -crf 23 -preset medium -c:a copy rotated.mp4Two 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
ffmpeg -display_rotation 90 -i input.mp4 -c copy rotated.mp4Writes 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)
ffmpeg -i phone.mp4 -c:v libx264 -crf 23 -preset medium -c:a copy fixed.mp4No 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
ffmpeg -noautorotate -i phone.mp4 -c:v libx264 -crf 23 -preset medium -c:a copy reencoded.mp4With -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.
{
"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
- ffmpeg resize videoResize a video with FFmpegRead
- ffmpeg crop videoCrop a video with FFmpegRead
- ffmpeg mov to mp4Convert MOV to MP4 with FFmpegRead