How to delete a single metadata item from an MP4 file

6,010

FFmpeg by default doesn't transfer most user metadata over, but it does transfer fields like rotation tag.

The command below instructs FFmpeg to transfer all metadata over but then overrides the rotation tag value.

ffmpeg -i in.mp4 -c copy -map_metadata 0 -metadata:s:v:0 rotate=0 -an out.mp4
Share:
6,010

Related videos on Youtube

Ali Hassan
Author by

Ali Hassan

Computer Scientist, Free Software Advocate, Wannabe Mathematician, attracted by beautiful Typography. I am, among many other things, the current author/maintainer of coursera-dl (get from PyPI: pip install coursera-dl) and a co-maintainer of edx-dl, two tools to help people download/archive videos (and other materials) from MOOCs, so that they can study at their convenience. I am also the current maintainer of the algorithms bundle for LaTeX, which includes the packages algorithm and algorithmic. It is openly developed at GitHub. By the way, my GitHub account also features many of my projects (and I am also collaborator on other repositories). I am also a proud Debian Maintainer (where I take care of circa 20 packages).

Updated on September 18, 2022

Comments

  • Ali Hassan
    Ali Hassan over 1 year

    Context and question

    I recorded a video with my MotoG3 phone Android phone and the resulting video (perhaps due to shaking the phone) plays rotated, that is, vertically, which is not something that I want. The video was saved in an MP4 container.

    Upon inspecting the file that was recorded, I saw (using both ffprobe and mediainfo) that it contains a flag that indicates that the video stream is rotated 90 degrees, which explains the rotation while playing the video. Here is the output from ffprobe:

    $ ffprobe -hide_banner ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2016-06-19 20:25:49
        com.android.version: 6.0
      Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
        Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
        Metadata:
          rotate          : 90
          creation_time   : 2016-06-19 20:25:49
          handler_name    : VideoHandle
          encoder         : MOTO
        Side data:
          displaymatrix: rotation of -90.00 degrees
        Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
        Metadata:
          creation_time   : 2016-06-19 20:25:49
          handler_name    : SoundHandle
    

    Since this video is from one rare event with my son, I would like to minimally change the video file, preferrably, only removing the rotation metadata and nothing else.

    Unfortunately, using information from other answers didn't help. I tried using:

    ffmpeg -i ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 -c copy -metadata:s:v:0 rotate=0 -an vid_20160619_170845475_unrotated.mp4
    

    But other metadata, like the date etc. are not present in the resulting file. This, in particular, makes organizer programs be confused while showing the files by date, among other things.

    Is there any way of minimally changing the input data (possibly remuxing it) so as to keep it as close as possible to the original data? In particular, I don't want to reencode the file.

    Any tools that are available under Linux are preferred.


    Extra information

    Since the full output of ffmpeg was asked, here it goes. This is a pure Debian testing userland.

    As a side note, ffmpeg is complaining about mismatched libraries because it is compiled two times in Debian, once without potentially problematic codecs and another with some extra codecs. I'm using the version with extra codecs, but I suppose that that doesn't matter, since only the muxing is being used here.

    Metadata before remuxing

    $ ffprobe  -hide_banner ~/Pictures/2016/06/19/vid_20160619_170845475.mp4
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2016-06-19 20:25:49
        com.android.version: 6.0
      Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
        Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
        Metadata:
          rotate          : 90
          creation_time   : 2016-06-19 20:25:49
          handler_name    : VideoHandle
          encoder         : MOTO
        Side data:
          displaymatrix: rotation of -90.00 degrees
        Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
        Metadata:
          creation_time   : 2016-06-19 20:25:49
          handler_name    : SoundHandle
    

    The remuxing process

    Note here that the audio metadata is not copied (which I expected, due to the -metadata:s:v:0 option) and ffmpeg tells me that it is copying the video metadata (without the rotation setting).

    $ ffmpeg -hide_banner -i ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 -c copy -metadata:s:v:0 rotate=0 -an vid_20160619_170845475_unrotated.mp4 
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2016-06-19 20:25:49
        com.android.version: 6.0
      Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
        Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
        Metadata:
          rotate          : 90
          creation_time   : 2016-06-19 20:25:49
          handler_name    : VideoHandle
          encoder         : MOTO
        Side data:
          displaymatrix: rotation of -90.00 degrees
        Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
        Metadata:
          creation_time   : 2016-06-19 20:25:49
          handler_name    : SoundHandle
    Output #0, mp4, to 'vid_20160619_170845475_unrotated.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        com.android.version: 6.0
        encoder         : Lavf57.25.100
        Stream #0:0(eng): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 17000 kb/s, 29 fps, 29.42 tbr, 90k tbn, 90k tbc (default)
        Metadata:
          encoder         : MOTO
          creation_time   : 2016-06-19 20:25:49
          handler_name    : VideoHandle
          rotate          : 0
    Stream mapping:
      Stream #0:0 -> #0:0 (copy)
    Press [q] to stop, [?] for help
    frame=29640 fps=403 q=-1.0 Lsize= 2121038kB time=00:17:01.91 bitrate=17003.0kbits/s speed=13.9x    
    video:2120800kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.011211%
    

    Metadata after remuxing

    Note here that there is no video metadata in the output, only container-level metadata.

    $ ffprobe -hide_banner vid_20160619_170845475_unrotated.mp4 
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'vid_20160619_170845475_unrotated.mp4':
      Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf57.25.100
      Duration: 00:17:01.95, start: 0.000000, bitrate: 17002 kb/s
        Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
        Metadata:
          handler_name    : VideoHandler