Rotate mp4 videos without re-encoding

I'm looking for a way to rotate videos shot with my Nexus 4 on my Debian Wheezy sytem. The videos are shot in portrait mode and I would like to rotate them to landscape mode. Preferably the rotation is command-line driven.

I have found several previous questions which are hinting at a good solution but I can't seem to manage to get it working.

To begin with there was this question: Rotating videos with FFmpeg

But it indicates that ffmpeg is outdated and that I should use avconv. I found this question detailing the way to go forward. https://askubuntu.com/questions/269429/how-can-i-rotate-video-by-180-degrees-with-avconv

This made me using following command:

avconv -i original.mp4 -vf "transpose=1" -codec:v libx264 -preset slow -crf 25 -codec:a copy flipped.mp4

However, this is painstakingly slow (last test took me more than 6 hours for less than 3 minutes of footage) and does not result in a playable movie. I also get an error in logging output which states Mb Rate > level limit.

Is there an issue here with the re-encoding? Should I first re-encode the videos from my phone to another, more "workable" encoding before applying the rotations? Or am I missing another important point?


If you just want to change the metadata such that mediaplayers that consider the flag play the file rotated, try something like:

ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=90 output.mp4

as found elsewhere on stackoverflow.


Rotation=0 fixed my issue. I started recording video in portrait mode, realized my mistake and immediately turn my phone to landscape to continue recording. My iphone had marked the video as portrait for the entire video.

ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=0 output.mp4

Fixed it.


FFmpeg and similar programs change the metadata even with the -map_metadata option. exiftool can read the rotation matrix and rotation flag, and since version 10.89 also write it as described below.

To get true lossless (incl. metadata) rotation, I couldn't find a solution, so I grabbed a hex editor (eg HxD) and analyzed the rotated video files.

True lossless rotation of MP4:

  • open mp4 with hex editor and search for vide to find the metadata of the video track

  • some rows above (for my files mostly 9, sometimes 12) you should see trak...\tkhd

  • in between there should be an @ sign (HEX 40)

  • in the two rows before it the rotation matrix is stored

  • no rotation:

     00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
     00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     40
    
  • 180°:

     FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
     FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00
     40
    
  • 90° cw:

     00 00 00 00 00 01 00 00 00 00 00 00 FF FF 00 00 
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
     40 
    
  • 90° ccw:

     00 00 00 00 FF FF 00 00 00 00 00 00 00 01 00 00 
     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
     40
    

Alter the file as you need it, and it should be rotated in players that support the rotation flag (most current players do).

In case your video contains stereo audio, this is obviously not switched, so in case you want the sound to match with video rotation (180°), you need to switch the left and right channels.

ExifTool lossless rotation:

Source.

Set rotation to 270°:

exiftool -rotation=270 FILE.mp4

Add 90° to existing rotation value:

exiftool "-rotation<${rotation;$_ += 90}" FILE.mp4

This answer is simply a summary of the comments provided by LordNeckbeard.

Rotating without encoding

Rotating without re-encoding is not possible unless:

  • your input is MJPEG
  • you rotate upon playback

Rotate with encoding using the correct ffmpeg

To correctly understand the steps needed to this, one should start by reading or at least skimming this question:

What are the differences and similarities between ffmpeg, libav, and avconv?

Summary: avconv is a fork of ffmpeg, debian maintainer chose avconv, you have to compile the correct ffmpeg from source.

The next step would be compiling the correct ffmpeg from source as is detailed here:

Compilation guide of ffmpeg for Debian

The final step is using the commands found in other posts:

How to flip a video 180° (vertical/upside down) with FFmpeg? or Rotating videos with FFmpeg

Summary: ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4