105

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?

braaterAfrikaaner
  • 1,072
  • 10
  • 20
stedes
  • 1,481
  • 3
  • 13
  • 17
  • 7
    `ffmpeg` from FFmpeg is not outdated. The fake, counterfeit "`ffmpeg`" from Libav (a fork of FFmpeg) is what is outdated. You can not rotate without re-encoding unless: 1) your input is MJPEG, or 2) you rotate upon playback. – llogan Jul 30 '14 at 22:36
  • @LordNeckbeard How can I tell the difference ? I used the package manager to install ffmpeg so I'm guessing I have the correct on ? – stedes Jul 31 '14 at 06:58
  • 1
    See [Who can tell me the difference and relation between ffmpeg, libav, and avconv?](http://stackoverflow.com/q/9477115/1109017) – llogan Jul 31 '14 at 16:35
  • 1
    As for rotating in general see [How to flip a video 180° (vertical/upside down) with FFmpeg?](http://superuser.com/a/578329), and for MJPEG inputs see [Losslessly rotate MJPEG video with ffmpeg and exiftran](http://ubuntuforums.org/showthread.php?t=2202695&p=12915259#post12915259). – llogan Jul 31 '14 at 16:42

5 Answers5

140

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.

Community
  • 1
  • 1
ruediger05
  • 1,432
  • 1
  • 10
  • 2
  • I tried this but no success. I'm using mplayer on Lubuntu. So, how to read the metadata to check if it was changed? – Sigur Aug 08 '15 at 11:49
  • 3
    @Sigur try `ffprobe -v quiet output.mp4 -show_streams|grep rot`. On a video where the rotation was successfully applied, I see this output: `TAG:rotate=90 rotation=-90` – kwc Aug 29 '15 at 19:40
  • 2
    Are there any explanations of the parameters? Eg. I've found one answer where the `:0` after `-metadata` isn't there - what does this do? What is `-c copy` for? .. – Dennis98 May 27 '16 at 01:56
  • This answer assumes the flag isn't already there. If it is, this command will basically just copy the file, and you'll actually need to get rid of the flag, or change it. Refer to Mangor's answer: https://stackoverflow.com/a/33204184/1450294 – Michael Scheper Jun 18 '17 at 17:44
  • 17
    Ok, just came across this question again but have much more experience with FFmpeg now. The `:s:v:0` after `-metadata` is the stream specifier, which just tells ffmpeg to which stream it should add the metadata. `:s` just stands for the streams of the input file, `:v` selects video streams and the number is the stream index, zero-based - so this will just select the first video stream. As you typically don't have more than one video stream, `:s:v` should result to the same. The `-c` option specifies the codec to be used, with `copy` for just copying the streams, without reencoding. – Dennis98 Aug 20 '17 at 22:23
  • This works great btw, and easy. Blaming myself for not having tried this today when knowing there's a tag for this.. ^^ – Dennis98 Aug 20 '17 at 22:24
  • 3
    Not all players will support this – Hamid Reza Jan 30 '18 at 13:37
  • @HamidReza I agree that in the past (say, prior to ~2015) lots of video playing software for Windows, macOS and iOS wouldn't respect metadata-based video rotation, but it's 2022 now and I think _every_ program I use _except for VLC_ does respect the `rotate` tag in videos using the MPEG-4 container format (regardless of the actual codec: HEVC/AVC/AV1, etc). And even though VLC doesn't seem to recognize it, VLC _does_ let you play the video _with rotation applied_ manually (via Tools > Effects > Geometry), which works for me. It's best to avoid re-encoding as much as possible. – Dai Mar 23 '22 at 03:18
  • This doesn't seem to work, I get this error: > [mp4 @ 0x55c2830a2440] Could not find tag for codec pcm_s16be in stream #1, codec not currently supported in container Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument Error initializing output stream 0:1 -- – Raleigh L. Jun 13 '22 at 00:04
  • Bizarrely, I needed to use a rotation value of 360 to make it rotate 270º. But it worked. Thanks. – Ryan Jul 09 '22 at 22:21
77

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
mrienstra
  • 508
  • 5
  • 7
aXeL-HH
  • 913
  • 1
  • 7
  • 8
  • 7
    I cannot understand how this did not get any upvotes. The other answers post plain lies that you cannot rotate losslessly a video unless it's MJPEG. This worked for me, it was lossless, no re-encoding (instant), and I have an assurance that nothing else in the file gets changed and I don't have to hassle with downloading random executable binaries off the net. This was even faster than setting up a command line from the accepted answer. Have an upvote and thanks! :) – deLock Jun 03 '18 at 11:19
  • 2
    Thx. I guess it's the problem of finding a better solution to an old question with multiple answers here on SX. There are actually multiple similar topics, which I tried to answer / help out with this info, but was blocked from other more elaborate users. More a discussion for SX meta, though. – aXeL-HH Jun 04 '18 at 11:54
  • 2
    Just tried it. Beautiful. It took only a few seconds, worked perfectly, and is 100% reversible to the original file. Thank you! – Spire Sep 24 '18 at 05:02
  • Can confirm it works in contrary to the accepted answer. Anyone haz teh code for that? – JackLeEmmerdeur Jan 03 '19 at 20:59
  • 1
    @user3469861 Code is integrated into exiftool v10.89, you might just want to use that: http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,6670.msg46809.html – aXeL-HH Jan 06 '19 at 21:28
  • The matrix in the mvhd and tkhd is 9 32 bit integers or 36 bytes; these examples are only showing 32 bytes, so they're missing one integer. – Paul Gregoire Sep 27 '19 at 20:43
  • 1
    For 0 degrees of rotation / no rotation, the example should most likely be ```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 00 00 00``` – Paul Gregoire Sep 27 '19 at 21:37
  • 2
    I have also baked this method into a [standalone tool](https://gitlab.com/AndreKR/mp4-rotator). – AndreKR Sep 30 '20 at 13:34
  • I love it, I however think it wont work for me. I am concatenating serval clips some of which are rotated 180°, they play back fine individually but once concatenated half are flipped. I wanted to avoid the losses that come with transcoding but I probably don't have a choice. Unless rotation information can be set multiple times in the stream but I somehow doubt it. – user2163234 Dec 22 '20 at 00:50
  • I want to cry. This is so simple, fast and awesome. You made my day! – Arthur Khazbs Mar 21 '21 at 21:56
  • found a python gist script to achieve this: https://gist.github.com/hajoscher/2b77247ed714207ba59d6b13c1371000 But what about other containers formats like avi, mkv? – ChenYang Mar 03 '22 at 07:40
  • A note: Smplayer (and probably mpv) doesn't use this information to play, when hardware acceleration is enabled. Smplayer v21.10, mpv v0.34.1, Devuan 5 Daedalus, GPU Radeon R7 240/340. – Alexey Vazhnov Jun 09 '22 at 18:43
  • @AlexeyVazhnov Smplayer uses this information but stretches the video into square (as with manual rotation in smplayer). – Alex78191 Feb 08 '23 at 00:47
56

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.

Mathias Bynens
  • 144,855
  • 52
  • 216
  • 248
Mangor
  • 585
  • 4
  • 3
  • 11
    Can you explain more this parameter please ? – Zulu Oct 18 '15 at 23:02
  • 1
    This doesn't actual rotate your video, though, does it? It simply tries to indicate to video players to play your video in a rotated fashion, but not all video players support that and it's not even a true rotation of the video, as far as I'm aware. – Raleigh L. Aug 30 '22 at 20:54
3

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

Community
  • 1
  • 1
stedes
  • 1,481
  • 3
  • 13
  • 17
2

There are several things that you've touched on in your question:

  1. There is almost no chance that you will able able to rotate without reencoding. The exception to that rule (MJPEG codec) has already been pointed out, but it's unlikely that you are using it, so it goes beyond the scope of this question. I will mention that the reason for this ability is that JPEG can be converted via metadata. Thus if you'll be able to find a container which has the metadata rotation, you'll be able to rotate, but none exist (or are wide spread enough) so far.

    an update: This answer now provides a way to losslessly rotate MP4 container.

  2. If it took your hours to rotate and reencode 3 minutes of the video, then the problem can lie on an enormous resolution. And i mean huge! Can you please provide the output of the avprobe original.mp4 so that it can be ascertained.

  3. Libav versus FFmpeg debates are very counterproductive (you can see that by the amount of fud posted here already). Basically what has happened was a split of the project with some developers going one way and some another, the fact that FFmpeg project has managed to keep the name is just a fluke and it makes no sense to call one project original and another a fork. The differences between projects are mostly in the development style and on the philosophy. If you would characterise FFmpeg as more Open Source and Libav as more Free Software, you'd not be all that mistaken. Rational people hope that eventually the developers will come to their senses, and maybe not merge the projects, but cooperate to the larger extent. When Ubuntu came out originally, on every Debian GNU/Linux chat there were huge messages along the line of "Ubuntu is NOT Debian!!!!!!!", but now the situation has calmed down and both sides are quite happy with one another.

v010dya
  • 5,296
  • 7
  • 28
  • 48
  • 5
    JPEG can also be rotated losslessly without changing the metadata – Walter Tross May 30 '15 at 15:48
  • @WalterTross As i understand the process that can only be done if the resolution is divisible by the block size, if not, then only by changing EXIF can you do this truly losslessly. Please correct me, if i'm wrong. – v010dya Nov 04 '17 at 11:47