21

I just want to change the rotation flag in a .mp4 video file. Many similar questions exist, most answers suggest using

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

My problem with those solutions is that even though it copies most of the metadata, some parts are lost, and the file is 700kb smaller. Attached is before and after metadata from ffprobe and exifer.

An additional odd finding is the ffmpeg rotate=90 command makes a ccw rotation, which in ffprobe is (cw) 270° in metadata, but (ccw)90° in displaymatrix side data.

= equal attributes
* altered attributes
- removed attributes
+ added attributes

ffprobe input.mp4

*Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\input.mp4':
=  Metadata:
*    major_brand     : avc1
*    minor_version   : 0
*    compatible_brands: avc1isom
=    creation_time   : 2016-10-29T12:10:41.000000Z
-    firmware        : HD3.11.03.03
*  Duration: 00:00:06.01, start: 0.000000, bitrate: 32072 kb/s
=    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1440 [SAR 1:1 DAR 4:3], 30945 kb/s, 47.95 fps, 47.95 tbr, 720k tbn, 95.90 tbc (default)
=    Metadata:
=      creation_time   : 2016-10-29T12:10:41.000000Z
*      handler_name    :  GoPro AVC
-      encoder         : GoPro AVC encoder
-    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
-    Metadata:
-      creation_time   : 2016-10-29T12:10:41.000000Z
-      handler_name    :  GoPro AAC

ffprobe output.mp4

*Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\output.mp4':
=  Metadata:
*    major_brand     : isom
*    minor_version   : 512
*    compatible_brands: isomiso2avc1mp41
=    creation_time   : 2016-10-29T12:10:41.000000Z
+    encoder         : Lavf58.10.100
*  Duration: 00:00:06.01, start: 0.000000, bitrate: 30948 kb/s
=    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1440 [SAR 1:1 DAR 4:3], 30945 kb/s, 47.95 fps, 47.95 tbr, 720k tbn, 95.90 tbc (default)
=    Metadata:
+      rotate          : 270
=      creation_time   : 2016-10-29T12:10:41.000000Z
*      handler_name    : VideoHandler
+    Side data:
+      displaymatrix: rotation of 90.00 degrees

exiftool input.mp4

=ExifTool Version Number         : 10.87
*File Name                       : input.mp4
=Directory                       : C:/
*File Size                       : 23 MB
*File Modification Date/Time     : 2016:10:29 13:10:48+02:00
*File Access Date/Time           : 2018:03:22 22:51:11+01:00
*File Creation Date/Time         : 2018:03:22 22:51:11+01:00
=File Permissions                : rw-rw-rw-
=File Type                       : MP4
=File Type Extension             : mp4
=MIME Type                       : video/mp4
*Major Brand                     : MP4 Base w/ AVC ext [ISO 14496-12:2005]
*Minor Version                   : 0.0.0
*Compatible Brands               : avc1, isom
=Movie Header Version            : 0
=Create Date                     : 2016:10:29 12:10:41
=Modify Date                     : 2016:10:29 12:10:41
*Time Scale                      : 90000
=Duration                        : 6.01 s
=Preferred Rate                  : 1
=Preferred Volume                : 100.00%
=Preview Time                    : 0 s
=Preview Duration                : 0 s
=Poster Time                     : 0 s
=Selection Time                  : 0 s
=Selection Duration              : 0 s
=Current Time                    : 0 s
*Next Track ID                   : 3
-Firmware Version                : HD3.11.03.03
-Lens Serial Number              : LW13121003000141
-Camera Serial Number Hash       : 4833422b363033313530636432356400
=Track Header Version            : 0
=Track Create Date               : 2016:10:29 12:10:41
=Track Modify Date               : 2016:10:29 12:10:41
=Track ID                        : 1
=Track Duration                  : 6.01 s
=Track Layer                     : 0
=Track Volume                    : 0.00%
=Image Width                     : 1920
=Image Height                    : 1440
=Graphics Mode                   : srcCopy
=Op Color                        : 0 0 0
=Compressor ID                   : avc1
=Source Image Width              : 1920
=Source Image Height             : 1440
=X Resolution                    : 72
=Y Resolution                    : 72
-Compressor Name                 : .GoPro AVC encoder
=Bit Depth                       : 24
-Color Representation            : nclc 1 1 1
-Gamma                           : 2.2
=Video Frame Rate                : 47.952
-Matrix Structure                : 1 0 0 0 1 0 0 0 1
=Media Header Version            : 0
=Media Create Date               : 2016:10:29 12:10:41
=Media Modify Date               : 2016:10:29 12:10:41
-Media Time Scale                : 48000
-Media Duration                  : 5.99 s
*Handler Type                    : Audio Track
-Handler Description             : .GoPro AAC
-Balance                         : 0
-Audio Format                    : mp4a
-Audio Channels                  : 2
-Audio Bits Per Sample           : 16
-Audio Sample Rate               : 48000
-Movie Data Size                 : 24045320
-Movie Data Offset               : 32768
*Avg Bitrate                     : 32 Mbps
=Image Size                      : 1920x1440
=Megapixels                      : 2.8
*Rotation                        : 0

exiftool output.mp4

=ExifTool Version Number         : 10.87
*File Name                       : output.mp4
=Directory                       : C:/
*File Size                       : 22 MB
*File Modification Date/Time     : 2018:03:23 12:29:19+01:00
*File Access Date/Time           : 2018:03:23 12:28:18+01:00
*File Creation Date/Time         : 2018:03:23 12:28:18+01:00
=File Permissions                : rw-rw-rw-
=File Type                       : MP4
=File Type Extension             : mp4
=MIME Type                       : video/mp4
*Major Brand                     : MP4  Base Media v1 [IS0 14496-12:2003]
*Minor Version                   : 0.2.0
*Compatible Brands               : isom, iso2, avc1, mp41
+Movie Data Size                 : 23232544
+Movie Data Offset               : 48
=Movie Header Version            : 0
=Create Date                     : 2016:10:29 12:10:41
=Modify Date                     : 2016:10:29 12:10:41
*Time Scale                      : 1000
=Duration                        : 6.01 s
=Preferred Rate                  : 1
=Preferred Volume                : 100.00%
=Preview Time                    : 0 s
=Preview Duration                : 0 s
=Poster Time                     : 0 s
=Selection Time                  : 0 s
=Selection Duration              : 0 s
=Current Time                    : 0 s
*Next Track ID                   : 2
=Track Header Version            : 0
=Track Create Date               : 2016:10:29 12:10:41
=Track Modify Date               : 2016:10:29 12:10:41
=Track ID                        : 1
=Track Duration                  : 6.01 s
=Track Layer                     : 0
=Track Volume                    : 0.00%
+Matrix Structure                : 0 1 0 -1 0 0 0 0 1
=Image Width                     : 1920
=Image Height                    : 1440
=Media Header Version            : 0
=Media Create Date               : 2016:10:29 12:10:41
=Media Modify Date               : 2016:10:29 12:10:41
+Media Time Scale                : 720000
+Media Duration                  : 6.01 s
+Media Language Code             : eng
+Handler Description             : VideoHandler
=Graphics Mode                   : srcCopy
=Op Color                        : 0 0 0
=Compressor ID                   : avc1
=Source Image Width              : 1920
=Source Image Height             : 1440
=X Resolution                    : 72
=Y Resolution                    : 72
=Bit Depth                       : 24
+Pixel Aspect Ratio              : 1:1
=Video Frame Rate                : 47.952
*Handler Type                    : Metadata
+Handler Vendor ID               : Apple
+Encoder                         : Lavf58.10.100
*Avg Bitrate                     : 30.9 Mbps
=Image Size                      : 1920x1440
=Megapixels                      : 2.8
*Rotation                        : 270

I compared ffmpeg rotate=0 and rotate=90 .mp4 files in notepad++ to identify the rotate flag / matrix, but without luck, just jibberish. I would prefer to just edit the flag (like exiftool is doing it for all kinds of metadata, but can't do rotate in videos) instead of streaming the content into a new container, also for faster processing (all videos are on NAS).

3 Answers 3

29

exiftool version 10.89 now has support to rotate mp4 videos without changing other metadata.

Usage:

exiftool -rotation=90 video.mp4
6
  • Didn't work for me for some reason.
    – Suncatcher
    Aug 10, 2018 at 13:48
  • Worked like a charm - thank you!
    – emrass
    Jun 30, 2019 at 17:10
  • 1
    @Suncatcher Try exiftool -rotation=0 video.mov. Makes no sense but it worked on my iPhone video. Nov 23, 2019 at 8:14
  • does not work with mkv.
    – bomben
    Mar 10, 2021 at 11:20
  • check version with 'exiftool -ver' . Default installation was 10.10 on an older Lubuntu 16, in Apr '21. Version 11.88 on a newer Lubuntu 20.
    – DragonLord
    Apr 14, 2021 at 1:21
24

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

  • 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.

5
  • @aXeL-HH You have any idea how this can be done in JAVA withouf using any external libraries?
    – ravi
    Oct 24, 2018 at 9:23
  • 1
    Best answer, imho. @ravi, if you know how to mess with binary data in files, you should be able to do this in any language platform.
    – Glitch
    Dec 16, 2018 at 6:48
  • @RiA, I will try.
    – ravi
    Dec 18, 2018 at 6:56
  • 1
    great! rough python code here: gist.github.com/hajoscher/2b77247ed714207ba59d6b13c1371000
    – cronos
    Mar 21, 2019 at 20:39
  • 1
    Can you flip or mirror y or x axis using this feature?
    – bryc
    Dec 6, 2020 at 20:10
-1

Some answers suggest that exiftool can't be used for this, but as of recent versions it definitely can.

exiftool -rotation=0 video.mp4 

This clears any rotation flags and assumes that the camera was used in it's normal (landscape) orientation. It does take about a minute which is surprising since it's only changing a couple bytes.

O:\>exiftool -ver
12.29

T:\>dir 2021*658*.mp4
 Volume in drive T is temp
 Volume Serial Number is 30A1-6AD0

 Directory of T:\

03/06/2021  02:45 PM       327,499,207 20210306_144335-00.00.00.000-00.01.32.658.mp4
               1 File(s)    327,499,207 bytes
               0 Dir(s)  16,700,923,904 bytes free

T:\>exiftool -rotation=0 20210306_144335-00.00.00.000-00.01.32.658.mp4
    1 image files updated

T:\>dir 2021*658*.mp4

12/07/2021  05:19 PM       327,499,207 20210306_144335-00.00.00.000-00.01.32.658.mp4
               1 File(s)    327,499,207 bytes
               0 Dir(s)  16,229,441,536 bytes free
6
  • How is this better than accepted answer?
    – Toto
    Dec 10, 2021 at 17:59
  • accepted answer has several comments that it doesn't work; this provides proof that it does leave the size unchanged and documents the version used.
    – Al Ro
    Dec 11, 2021 at 18:06
  • Sorry, but accepted answer doesn't have any negative comments.
    – Toto
    Dec 11, 2021 at 18:10
  • " Didn't work for me for some reason. – Suncatcher Aug 10 '18 at 13:48 "
    – Al Ro
    Dec 12, 2021 at 0:08
  • This comment isn't attach to accepted answer.
    – Toto
    Dec 12, 2021 at 9:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.