如何从 MP4 文件中删除单个元数据项

rbr*_*ito 6 video metadata ffmpeg video-conversion

背景和问题

我用我的 MotoG3 手机 Android 手机录制了一个视频,生成的视频(可能是由于晃动手机)旋转播放,即垂直播放,这不是我想要的。视频保存在 MP4 容器中。

在检查录制的文件时,我看到(同时使用ffprobemediainfo)它包含一个标志,指示视频流旋转了 90 度,这解释了播放视频时的旋转。这是以下的输出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
Run Code Online (Sandbox Code Playgroud)

由于该视频来自我儿子的一次罕见活动,因此我想对视频文件进行最小程度的更改,最好只删除旋转元数据,而不删除其他内容。

不幸的是,使用其他答案中的信息并没有帮助。我尝试使用:

ffmpeg -i ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 -c copy -metadata:s:v:0 rotate=0 -an vid_20160619_170845475_unrotated.mp4
Run Code Online (Sandbox Code Playgroud)

但其他元数据(例如日期等)不会出现在结果文件中。尤其是,这使得组织者程序在按日期显示文件等时感到困惑。

有没有办法最小化地改变输入数据(可能重新混合它),以使其尽可能接近原始数据?特别是,我不想重新编码该文件。

Linux 下可用的任何工具都是首选。


额外的信息

由于询问了 ffmpeg 的完整输出,所以就这样了。这是一个纯粹的 Debian 测试用户区。

附带说明一下,ffmpeg 抱怨库不匹配,因为它在 Debian 中编译了两次,一次没有可能有问题的编解码器,另一次带有一些额外的编解码器。我使用带有额外编解码器的版本,但我认为这并不重要,因为这里只使用了复用器。

重新混合之前的元数据

$ 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
Run Code Online (Sandbox Code Playgroud)

重新复用过程

请注意,此处未复制音频元数据(由于该-metadata:s:v:0选项,这是我所期望的),并且 ffmpeg 告诉我它正在复制视频元数据(没有旋转设置)。

$ 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%
Run Code Online (Sandbox Code Playgroud)

重新混合后的元数据

这里请注意,输出中没有视频元数据,只有容器级元数据。

$ 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
Run Code Online (Sandbox Code Playgroud)

Gya*_*yan 5

默认情况下,FFmpeg 不会传输大多数用户元数据,但它会传输旋转标签等字段。

下面的命令指示 FFmpeg 传输所有元数据,但随后覆盖旋转标签值。

ffmpeg -i in.mp4 -c copy -map_metadata 0 -metadata:s:v:0 rotate=0 -an out.mp4
Run Code Online (Sandbox Code Playgroud)