I have a video that was rotated 180° when recorded. Is it possible to correct this with FFmpeg?
-
Are you asking about flipping it during a playback or re-encoding with correct orientation? – Mxx Apr 05 '13 at 06:37
-
@Mxx I was thinking re-encoding, but what did you mean by during playback? – Louis Waweru Apr 05 '13 at 06:38
-
Media players that use ffmpeg as a decoding backend can also utilize all of its filters. See this screenshot http://ffdshow-tryout.sourceforge.net/images/front1.png "Offset and flip" filter. Also see http://stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg – Mxx Apr 05 '13 at 06:44
-
Oh okay, cool. That would work for me, but I also want to share it. I'll take a look at the SO question. – Louis Waweru Apr 05 '13 at 06:46
-
6The wording and title of this question is really confusing. Flipping a video vertically is not the same as rotating it 180 degrees (which is the same as a vertical flip *and* a horizontal flip). Based on the accepted answer I'm editing to specify rotation. Currently this is polluting google results for vertically flipping videos with ffmpeg. – Jason C Jan 27 '16 at 02:37
-
[A similar question on Stack Overflow](https://stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg) (referenced in a comment to [a meta question](https://meta.stackoverflow.com/questions/423875/my-post-keeps-getting-downvoted-for-no-obvious-reason) (likely to be automatically deleted within a few days or weeks)). – Peter Mortensen Mar 29 '23 at 11:00
8 Answers


tl;dr
ffmpeg will automatically rotate the video unless:
- your input contains no rotate metadata
- your
ffmpegis too old
Rotation metadata
Some videos, such as from iPhones, are not physically flipped, but contain video stream displaymatrix side data or rotate metadata. Some players ignore these metadata and some do not. Refer to ffmpeg console output to see if your input has such metadata:
$ ffmpeg -i input.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Duration: 00:00:05.00, start: 0.000000, bitrate: 43 kb/s
Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 39 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
rotate : 180
Side data:
displaymatrix: rotation of -180.00 degrees
Autorotation
ffmpeg will automatically physically rotate the video according to any existing video stream rotation metadata.
You need a build that includes commit 1630224, from 2 May 2015, to be able to use the autorotation feature.
Example
ffmpeg -i input.mp4 -c:a copy output.mp4
To disable this behavior use the -noautorotate option.
If the input contains no metadata or if your ffmpeg is old
You will have to use a filter to rotate the video, and if any rotate metadata exists it will have to be removed as shown in the examples below:
Examples
Using ffmpeg you have a choice of three methods of using video filters to rotate 180°.
hflip and vflip
ffmpeg -i input.mp4 -vf "hflip,vflip,format=yuv420p" -metadata:s:v rotate=0 \
-codec:v libx264 -codec:a copy output.mkv
transpose
ffmpeg -i input.mp4 -vf "transpose=2,transpose=2,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
rotate
This filter can rotate to any arbitrary angle and uses radians as a unit instead of degrees. This example will rotate π/1 radians, or 180°:
ffmpeg -i input.mp4 -vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
You can use degrees instead. One degree is equal to π/180 radians. So if you want to rotate 45°:
ffmpeg -i input.mp4 -vf "rotate=45*(PI/180),format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4
When using the rotate filter, the bilinear interpolation should be turned off (by using bilinear=0) for angles divisible by 90, otherwise it may look blurry.
Notes
Filtering requires encoding. These examples make H.264 video outputs. See the FFmpeg H.264 Video Encoding Guide for guidance on getting the quality you want.
Chroma subsampling. I included
format=yuv420psinceffmpegwill attempt to minimize or avoid chroma subsampling (depending on the encoder, input,ffmpegversion, etc). This is good behavior in a purely technical sense, but most players are incompatible with more "advanced" chroma subsampling schemes. This is the same as using-pix_fmt yuv420, but is conveniently located in the filterchain.Copy the audio. The
-codec:a copyoption will stream copy (re-mux) instead of encode. There is no reason to re-encode the audio if you just want to manipulate the video only (unless you want to convert to a different audio format). This will save time since encoding is time consuming and it will preserve the quality of the audio.
Rotate upon playback
Alternatively you can rotate upon playback and avoid re-encoding. ffplay will automatically rotate:
ffplay input.mp4
If there is no displaymatrix side data or rotate metadata then you can use filters:
ffplay -vf "hflip,vflip" -i input.mp4
...or refer to your favorite player. Most players worth using, like VLC, have this capability.
Getting ffmpeg
Older builds of ffmpeg do not include filtering capabilities. See the FFmpeg download page for several options including convenient builds for Linux, OS X, and Windows, or refer to the FFmpeg Wiki for step-by-step ffmpeg compile guides.
- 57,139
- 15
- 118
- 145
-
Thanks, I just finished trying `-vf vflip` and it worked like a charm. But it was a re-encode. I'm not sure if I'm reading you right. Are you saying `-vf hflip,vflip` won't re-encode? – Louis Waweru Apr 05 '13 at 06:52
-
@Louis `ffmpeg` requires that you re-encode when using video and audio filters. However, `ffplay` can also utilize many of the filters during playback as shown in my second example. – llogan Apr 05 '13 at 06:55
-
-
1I wonder if there's a way of preserving video quality other than `-codec:v libx264`? Can `ffmpeg` just use the same encoding without user trying to figure it out? – Sadi Oct 03 '13 at 10:15
-
@Sadi No. You must re-encode when using filters, but that does not mean it has to look bad. See the [FFmpeg and x264 Encoding Guide](https://trac.ffmpeg.org/wiki/x264EncodingGuide) and use the lowest `-crf` value that still looks good to you (a good range is ~18-24), or if in a hurry just use `-crf 18`. – llogan Oct 03 '13 at 16:10
-
Thanks, it seems the default value for `-crf` (23) is good enough for me, using only `-vcodec libx264` parameter. I was actually hoping for something to even save me from specifying video codec such as `libx264` in the command line so that I can use it in a **Nautilus Script** for rotating almost any video file. Perhaps I can try and find a way of inserting it by using the video codec info embedded in the file. – Sadi Oct 03 '13 at 17:20
-
This is it: `compressor=$(exiftool -a -s -CompressorName "$file" | awk -F ': ' '{print $2}' | sed -e 's/H\.264/libx264/g')` Now I just need to add the other pairs to **H.264 - libx264** in this variable. – Sadi Oct 03 '13 at 17:49
-
@LordNeckbeard Ahh, I still come back to this months later. Would you be willing to take a bounty to explain `"180*(PI/180)"` in a more accessible way? – Louis Waweru Dec 10 '13 at 04:51
-
1@Louis `rotate` uses [radians](http://en.wikipedia.org/wiki/Radian) as a unit instead of degrees. I think people are more familiar with degrees, so I attempted to show how to use degrees in the example. One degree is equal to π/180 radians. So if you want to rotate 45° simply use `rotate="45*(PI/180)"`. – llogan Dec 10 '13 at 18:27
-
`Unrecognized option 'codec:a' Failed to set value 'copy' for option 'codec:a'` – Gringo Suave Jan 06 '14 at 20:53
-
@GringoSuave Quit using an ancient ffmpeg. See the [FFmpeg Wiki](http://trac.ffmpeg.org/wiki/) for compile guides or simply download a recent build via the [FFmpeg Download](http://ffmpeg.org/download.html) page. If you must use your graybeard, outdated ffmpeg use `-acodec` instead. – llogan Jan 06 '14 at 21:10
-
Ok, thanks. Was trying what came with latest Ubuntu. Tried avconv as well but the quality drop was huge. – Gringo Suave Jan 06 '14 at 21:22
-
Due to FFMPEG recently implementing auto rotation this will actually break if you update to 2.7. I posted a new answer on how to deal with this: http://superuser.com/questions/578321/how-to-flip-a-video-180%C2%B0-vertical-upside-down-with-ffmpeg#929188 – Albin Jun 17 '15 at 17:33
-
@llogan Thank you, very detailed and informative answer. I wonder if i want to do flipping/mirroring from C Lib do I need to create a filter. I have checked [hflip](http://patches.ffmpeg.org/doxygen/trunk/hflip_8h_source.html) but not sure how to use it. Again, thanks alot!! – Sam Jun 11 '19 at 18:36
-
@Sam I only use the cli tool, but I don't see why you would need to write a filter. Filter is located at `libavfilter/vf_hflip.c` in source code. Also see `doc/examples`. – llogan Jun 11 '19 at 19:09
-
@llogan You are right, I don't need to create any filters, it's already there. Also I managed to do the horizontal flipping myself without using `hflip` with Google help ;) .. This is how i did it, hope to help others: – Sam Jun 11 '19 at 19:32
-
`void flip_horizontal( uint8_t array[], unsigned int cols, unsigned int rows ) { unsigned int left = 0; unsigned int right = cols-1; int r; for(r = 0; r < rows; r++){ while(left != right && right > left){ int index1 = r * cols + left; int index2 = r * cols + right; int temp = array[index1*3]; array[index1*3] = array[index2*3]; array[index2*3] = temp; temp = array[index1*3+1]; array[index1*3+1] = array[index2*3+1]; array[index2*3+1] = temp; temp = array[index1*3+2]; array[index1*3+2] = array[index2*3+2]; array[index2*3+2] = temp; right--; left++; } left = 0; right = cols-1; } }` – Sam Jun 11 '19 at 19:32
-
@llogan I have `ffmpeg` that is not old. Is there a video stream FLIP metadata in the h264 format so that I can avoid using video filters ? – SebMa Apr 14 '21 at 08:01
-
@llogan Neither `flip` nor `rotate` appear in the documentation link you gave. Shouldn't the `rotate` metadata at least appear in there given that it's already being used to rotate a mp4 video losslessly ? – SebMa Apr 14 '21 at 16:18
-
@SebMa I misunderstood your question. Yes, you can set the rotate metadata: `ffmpeg -i input.mp4 -c copy -metadata:s:v rotate=90 output.mp4` – llogan Apr 14 '21 at 16:30
-
@llogan In fact, you didn't :) . I was just wondering if the `rotate` metadata keyword was missing from that documentation, than maybe the `flip` metadata could be used also to modify the video losslessly. – SebMa Apr 14 '21 at 16:34
-
@SebMa The name of the h264_metadata bitstream filter might be confusing. It is not used to set arbitrary metadata, but only certain aspects specific to the H.264 video bitstream. I'm not sure if you can use it to do any rotation without looking into it further. – llogan Apr 14 '21 at 16:41
-
@llogan OK. So if I get it right. Video H.264 bitstream metadata has nothing to do with H.264 metadata (where the rotate metadata is located for example). Do you have a documentation that list all the possible H.264 metadata fields ? – SebMa Apr 14 '21 at 18:48
FFmpeg changed the default behavior to auto rotate input video sources with "rotate" metadata in the v2.7 release in 2015.
If you know your script or command will never run on FFmpeg releases older than 2.7, the simplest solution is to remove any custom rotation based on metadata.
For other cases, you can future-proof by keeping your custom rotation code and adding the -noautorotate flag (this is supported in older versions which were still maintained at the time).
- 12,090
- 23
- 70
- 90
- 180
- 1
- 4
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4
Did the trick for me. I am not sure why the transpose filter does not provide a possibility to rotate 180 degrees at once, but whatever.
Check the documentation for more information.
- 12,090
- 23
- 70
- 90
- 151
- 5
Media players that use FFmpeg as a decoding backend can also utilize all of its filters. See this screenshot with "Offset & flip" filter. 
Alternatively, if you want to re-encode your video, check out Rotating videos with FFmpeg on Stack Overflow.
- 12,090
- 23
- 70
- 90
- 2,791
- 2
- 19
- 35
-
1Unfortunately the `transpose` filter referenced in [Rotating videos with FFmpeg](http://stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg) will not rotate 180° as far as I can tell. – llogan Apr 05 '13 at 07:06
-
1@LordNeckbeard not directly, but you can chain two `transpose` filters together to achieve the effect. – evilsoup Apr 05 '13 at 08:56
-
1@evilsoup Ah, yes, I didn't think of that. Spatial reasoning is hard; let's go shopping. Feel free to update my answer with an example. – llogan Apr 07 '13 at 02:17
At the end you'll find the two consecutive FFmpeg commands that successfully rotated my video to the correct orientation. It seems to me the purpose of hflip and vflip in FFmpeg, is, at minimum, confusing, and contrary to what I expected.
The file merlin.mov is a copy of a video I took on my iPhone, first uploaded to Dropbox, and then downloaded to my laptop, running Ubuntu:
uname -a
Output:
Linux gazelle 3.13.0-135-generic #184-Ubuntu SMP Wed Oct 18 11:55:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
I know I should've been able to mount my iPhone via USB and copied the files directly, but that didn't work; my laptop would recognize the iPhone was connected, but it wouldn't mount its filesystem, and I got no prompt on my iPhone to "trust" the laptop.
The command I used to copy from Dropbox to my laptop was this:
cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
merlin.mov
The original file is Video 1920 x 1080 Codec HEVC/H.265 frame rate 30/sec, bitrate 8140 kbit/s, Audio Codec MPEG-4 AAC audio Channels Stereo, sample rate 44100 Hz, bitrate 85 kbit/s. When I play it on my iPhone it's oriented properly, and the sound is synchronized.
When I play it in videos on my laptop it's both upside down and reversed horizontally, and the sound isn't synchronized. Here's partial output from "ffmpeg -i merlin.mov":
Metadata:
rotate : 180
creation_time : 2017-11-02T14:41:55.000000Z
handler_name : Core Media Data Handler
encoder : HEVC
Here's the first line of output from "ffmpeg -version":
ffmpeg version 3.3.3 Copyright (c) 2000-2017 the FFmpeg developers
The following left the playback inverted both vertically and horizontally, though it did convert to MPEG-4 video (video/MP4) and synchronized the sound:
ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4
The following inverted vertically so the playback is upright, synchronized the sound, and converted to MPEG-4, but it left the horizontal incorrectly flipped end for end (this isn't a typo; I did specify 'hflip'):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
The following flipped the horizontal to the correct orientation, but it left the playback upside down:
ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4
The following didn't seem to have any effect whatsoever:
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4
I also tried this, based on a command I found at superuser.com. It successfully synchronized the sound, and converted to MPEG-4, but both horizontal and vertical orientation remained incorrect:
ffmpeg -i merlin.mov \
-vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 \
-codec:a copy merlinrotate.mp4
I also tried this, which didn't work either in terms of correcting the orientation:
ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4
The following two-step process finally got what I wanted; vertical and horizontal both flipped, sound synchronized, and format converted to MPEG-4 (again, this isn't a typo; I used hflip in both commands):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
- 12,090
- 23
- 70
- 90
- 21
- 3
-
While long - this does look like an answer to me - he's simply walked through his problem solving process. – Journeyman Geek Nov 08 '17 at 03:52
-
@JourneymanGeek Indeed you are correct. I now see in his final paragraph *The following 2-step process finally got what I wanted*. Good eye. (I really did read the whole post but my eyes probably had glazed over by the time I got there). – I say Reinstate Monica Nov 09 '17 at 17:46
-
Good job improving your answer. You have done well to include sufficient detail for your answer. As you have a look around the site, try to observe how other good answers balance clarity with detail. – I say Reinstate Monica Nov 10 '17 at 02:06
Following is a Bash script which will output the files with the directory structure under "fixedFiles". It transforms and rotates iOS videos and transcodes AVI files. The script relies on having installed both ExifTool and FFmpeg.
#!/bin/bash
# Rotation by 90 degrees. It will have to concatenate.
#ffmpeg -i <originalfile> -metadata:s:v:0 rotate=0 -vf "transpose=1" <destinationfile>
#/VLC -I dummy -vvv <originalfile> --sout='#transcode{width=1280,vcodec=mp4v,vb=16384,vfilter={canvas{width=1280,height=1280}:rotate{angle=-90}}}:std{access=file,mux=mp4,dst=<outputfile>}\' vlc://quit
# Allowing blanks in file names
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
# Bit Rate
BR=16384
# Where to store fixed files
FIXED_FILES_DIR="fixedFiles"
#rm -rf $FIXED_FILES_DIR
mkdir $FIXED_FILES_DIR
# VLC
VLC_START="/Applications/VLC.app/Contents/MacOS/VLC -I dummy -vvv"
VLC_END="vlc://quit"
#############################################
# Processing of MOV in the wrong orientation
for f in `find . -regex '\./.*\.MOV'`
do
ROTATION=`exiftool "$f" |grep Rotation|cut -c 35-38`
SHORT_DIMENSION=`exiftool "$f" |grep "Image Size"|cut -c 39-43|sed 's/x//'`
BITRATE_INT=`exiftool "$f" |grep "Avg Bitrate"|cut -c 35-38|sed 's/\..*//'`
echo Short dimension [$SHORT_DIMENSION] $BITRATE_INT
if test "$ROTATION" != ""; then
DEST=$(dirname ${f})
echo "Processing $f with rotation $ROTATION in directory $DEST"
mkdir -p $FIXED_FILES_DIR/"$DEST"
if test "$ROTATION" == "0"; then
cp "$f" "$FIXED_FILES_DIR/$f"
elif test "$ROTATION" == "180"; then
#$(eval $VLC_START \"$f\" "--sout="\'"#transcode{vfilter={rotate{angle=-"$ROTATION"}},vcodec=mp4v,vb=$BR}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
$(eval ffmpeg -i \"$f\" -vf hflip,vflip -r 30 -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\")
elif test "$ROTATION" == "270"; then
$(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=2,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )
else
#$(eval $VLC_START \"$f\" "--sout="\'"#transcode{scale=1,width=$SHORT_DIMENSION,vcodec=mp4v,vb=$BR,vfilter={canvas{width=$SHORT_DIMENSION,height=$SHORT_DIMENSION}:rotate{angle=-"$ROTATION"}}}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
echo ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\"
$(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )
fi
fi
echo
echo ==================================================================
sleep 1
done
#############################################
# Processing of AVI files for my Panasonic TV
# Use ffmpegX + QuickBatch. Bitrate at 16384. Camera resolution 640x424
for f in `find . -regex '\./.*\.AVI'`
do
DEST=$(dirname ${f})
DEST_FILE=`echo "$f" | sed 's/.AVI/.MOV/'`
mkdir -p $FIXED_FILES_DIR/"$DEST"
echo "Processing $f in directory $DEST"
$(eval ffmpeg -i \"$f\" -r 20 -acodec libvo_aacenc -b:a 128k -vcodec mpeg4 -b:v 8M -flags +aic+mv4 \"$FIXED_FILES_DIR/$DEST_FILE\" )
echo
echo ==================================================================
done
IFS=$SAVEIFS
- 12,090
- 23
- 70
- 90
- 11
- 2
In case your video doesn't have rotation metadata as explained in llogan's answer, you can add the metadata to rotate the video without re-encoding, and it should work in most places.
ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=180 output.mp4
(Command copied from this answer to another question in StackOverflow)
- 101
- 3
Here are the steps:
First open your video file in QuickTime. You can either fire up QuickTime first, go to “File” and then down to “Open File”. Or you could right-click the file itself, choose “Open With” and then choose QuickTime.
Once the video is open click “Edit” and you’ll then find the rotate and flip options straight below
Once you’ve locked the orientation you want, you then have to export your video with the new changes you’ve added. You’ll find the “Export” option under the “File” menu in QuickTime.
Choose the file settings you want to export as and click “Ok”, to kick off the export.
When the export operation is complete, you’ll find your new file where ever you chose to save it with the correct orientation!
This whole fix took me less than 5 minutes to complete, but depending on the length of the video, it could take much longer (or shorter, again, it varies).
- 12,090
- 23
- 70
- 90
- 101
- 1