Change rotation flag in MP4 video (without losing metadata)

19,751

Solution 1

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.

Solution 2

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

Usage:

exiftool -rotation=90 video.mp4
Share:
19,751

Related videos on Youtube

aXeL-HH
Author by

aXeL-HH

BY DAY: Problem causer. BY NIGHT: Problem solver. FOR FUN: Dropping my anchor outside of my comfort zone.

Updated on September 18, 2022

Comments

  • aXeL-HH
    aXeL-HH over 1 year

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

  • Suncatcher
    Suncatcher almost 6 years
    Didn't work for me for some reason.
  • ravi
    ravi over 5 years
    @aXeL-HH You have any idea how this can be done in JAVA withouf using any external libraries?
  • Glitch
    Glitch over 5 years
    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.
  • ravi
    ravi over 5 years
    @RiA, I will try.
  • cronos
    cronos about 5 years
  • emrass
    emrass almost 5 years
    Worked like a charm - thank you!
  • pacoverflow
    pacoverflow over 4 years
    @Suncatcher Try exiftool -rotation=0 video.mov. Makes no sense but it worked on my iPhone video.
  • bryc
    bryc over 3 years
    Can you flip or mirror y or x axis using this feature?
  • bomben
    bomben about 3 years
    does not work with mkv.
  • DragonLord
    DragonLord about 3 years
    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.
  • Toto
    Toto over 2 years
    How is this better than accepted answer?
  • Al Ro
    Al Ro over 2 years
    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.
  • Toto
    Toto over 2 years
    Sorry, but accepted answer doesn't have any negative comments.
  • Al Ro
    Al Ro over 2 years
    " Didn't work for me for some reason. – Suncatcher Aug 10 '18 at 13:48 "
  • Toto
    Toto over 2 years
    This comment isn't attach to accepted answer.
  • Al Ro
    Al Ro over 2 years
    the accepted answer of using a hex editor is certainly interesting and useful, but way beyond what most people can do.
  • Admin
    Admin almost 2 years
    @pacoverflow This does make sense, because the video is encoded in landscape, it's only marked as "rotated 90 degrees" to tell video players to render it in portrait (rotating 90 degrees after decoding). This is probably because the encoding is done by hardware. Always encoding in the same orientation could simplify hardware design, I imagine.