Turn or mirror a video in the pixels rather than in a container flag, so it is upright everywhere. Says where each edge of the source will end up, composes the turn and the mirror in a stated order, and always writes MP4.
Initializing in your browser…
Play a video backwards, or forward and then backward, at a speed that reaches the file. Reverse the sound, keep it running forwards, or drop it. The memory a reversal needs is worked out from your own clip.
Cut a clip out of a video, choosing whether the cut lands on the exact frame (re-encodes to MP4) or leaves the streams untouched (instant and lossless, but only at a keyframe). The result says which ran and reads the real length back off the file.
Convert a video between MP4, WebM, OGG, MOV, AVI and MKV, each naming the codecs it really writes and each producing a file that actually plays. One quality dial normalised into four different encoder scales.
A clip with a red band across the top and a blue band down the left, turned a quarter clockwise and then mirrored.
Input
bands.mp4 640x480 - 90 degrees CW - Flip H
Output
480x640 with the red band on the LEFT and the blue band along the top
A turn and a mirror do not commute, so the order has to be stated: this turns first and mirrors second. The preview used to compose them the other way round, because CSS applies its transform functions right to left, so with both switched on it showed the red band on the opposite side from the file it produced. Both now read the same plan, which also prints where every edge of the source ends up.
There are two ways a video can be sideways, and only one of them is about the pixels. A phone writes an upright picture and a note in the container saying which way to turn it for display, so a player that reads the note shows it correctly and one that ignores the note shows it on its side. This tool turns the PICTURES, so the result is right everywhere, and it turns what you are actually looking at: ffmpeg applies the container note when it decodes, so a clip already tagged 90 degrees is turned from the orientation you see rather than from the orientation stored, and the output carries no note of its own because it no longer needs one. The filter map behind the buttons was checked rather than assumed, on a clip with a red band across the top and a blue band down the left side: a quarter turn clockwise puts the red on the right and the blue along the top; anticlockwise puts the red on the left; a half turn puts the red on the bottom and the blue on the right. Every one of those is what it should be, and the page now prints the same thing in words before you run it, so the explanation and the file cannot drift apart.
Turn the pixels rather than the tag, so the clip is upright in editors and uploaders that ignore the tag.
Front cameras often store the mirrored image. Flip H on its own fixes that without any turn.
A camera mounted inverted needs a half turn, which is two quarter turns and leaves the frame size alone.
A quarter turn swaps the frame size, so a 1920 by 1080 clip becomes 1080 by 1920. That is a turn, not a crop: nothing is cut off.
The one thing this tool got wrong was not the turn, it was the order.
A turn and a mirror do not commute. Turning a picture a quarter clockwise and then mirroring it left to right is a different picture from mirroring first and turning second. ffmpeg's chain is transpose then hflip, which turns first; the on-screen preview built its own CSS as `rotate(90deg) scaleX(-1)`, and CSS applies its functions right to left, so that mirrors first. With both switched on, the preview showed the red band on one side and the file had it on the other. Both now come from the same plan, which states the order (turn first, mirror second) and works out where every edge of the source ends up. The page prints that too: "the top edge ends up on the left".
The other fix is the container. Applying a turn re-encodes the video with libx264, and the output used to be given the input's extension, so turning a WebM produced a file named .webm with H.264 inside it. The output is now always MP4. Audio is copied through untouched when MP4 can hold it (AAC, MP3, AC-3, ALAC) and re-encoded to AAC by name when it cannot (Opus, Vorbis), and it can also be dropped. Selecting nothing and pressing Apply copies both streams rather than re-encoding for no reason.
The editor shows the original and the transformed preview side by side, reports the source and output frame sizes (a quarter turn swaps them, so 1920 by 1080 becomes 1080 by 1920), and offers four one-click presets built on the same transforms. Keyboard shortcuts: R turns clockwise, Shift and R anticlockwise, H and V mirror, Space plays and pauses, Escape resets. After a run the page reads the frame size back off the file it made and shows it against the size it predicted, along with the file size, the time taken and the exact ffmpeg command.
The pixels. A container rotation flag is what phones write and what some players ignore, which is why a clip can look upright in one app and sideways in another. This re-encodes the frames in their new orientation and the output carries no rotation flag at all.
No. ffmpeg applies the container rotation when it decodes, so the tool turns the picture you are looking at. A clip tagged 90 degrees that displays as 480 by 640 with a red band on the left comes back 640 by 480 with the red band on top after another quarter turn clockwise, which is one turn, not two.
Because they are different pictures: turning and mirroring do not commute. This tool turns first and mirrors second, and it says so. The preview used to compose them the other way round, so with both switched on it showed a different result from the file it produced.
A turn cannot be done without re-encoding the video, so there is one generation of H.264 loss at the CRF you choose (20 by default, which is above the usual near-transparent setting). The audio is copied byte for byte when the container allows it, so that loses nothing at all. Selecting no transform at all copies both streams and loses nothing.
Because the video inside it is now H.264, and a container has to match its contents. The previous version kept the input extension, which produced files nothing could open.
Video is decoded and re-encoded on your own device. Large files never leave your machine.