为什么剥离元数据会导致我的 MP3 文件的时长减少 0.03 秒?

为什么剥离元数据会导致我的 MP3 文件的时长减少 0.03 秒?

我有一个文件 input.mp3,在其上运行 ffprobe 得到以下结果:

[mp3 @ 0x559431400a00] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from '../backup/1.mp3':
  Metadata:
    album           : DW01-The Colour Of Magic
    artist          : Terry Pratchett
    album_artist    : Terry Pratchett
    comment         : Read By Nigel Planer
    composer        : Nigel Planer
    genre           : Discworld
    publisher       : Polygram
    title           : Colour Of Magic 1 of 6
    track           : 1
    date            : 1983
    id3v2_priv.WM/Provider: A\x00M\x00G\x00\x00\x00
    id3v2_priv.WM/WMCollectionGroupID: \xe4\xbba\xf0\xf2\xcd.D\xab\x92b\xeb{\x8b\x9a\xce
    id3v2_priv.WM/WMCollectionID: \xe4\xbba\xf0\xf2\xcd.D\xab\x92b\xeb{\x8b\x9a\xce
    id3v2_priv.WM/UniqueFileIdentifier: A\x00M\x00G\x00a\x00_\x00i\x00d\x00=\x00R\x00 \x00 \x00 \x002\x007\x007\x008\x004\x003\x00;\x00A\x00M\x00G\x00p\x00_\x00i\x00d\x00=\x00P\x00 \x00 \x00 \x00 \x00 \x00 \x003\x003\x007\x00;\x00A\x00M\x00G\x00t\x00_\x00i\x00d\x00=\x00T\x00 \x00 \x001\x005\x00
    id3v2_priv.WM/WMContentID: h\x86H@^\xe6qF\x95T\x04m\x01P\x90\x7f
    id3v2_priv.WM/MediaClassSecondaryID: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
    id3v2_priv.WM/MediaClassPrimaryID: \xbc}`\xd1#\xe3\xe2K\x86\xa1H\xa4*(D\x1e
    id3v2_priv.ZuneCollectionID: \x1d\xcb\xdf\xf3X89D\x81\xd1\xd0s#P\x00\xf8
  Duration: 01:08:19.30, start: 0.000000, bitrate: 32 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 32 kb/s
    Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 274x417, 90k tbr, 90k tbn, 90k tbc (attached pic)
    Metadata:
      comment         : Cover (front)

我想要对这个文件做各种事情,比如将它与其他文件连接起来,然后将其拆分成小段。但现在,我只会考虑删除元数据的简单情况,因为这本身会产生与我在其他操作中遇到的问题类似的问题。当我对上述文件运行以下命令时:

ffmpeg -i input.mp3 -map 0:a -c:a copy -map_metadata -1 output.mp3

然后我在 output.mp3 上运行 ffprobe

Input #0, mp3, from 'output.mp3':
  Metadata:
    encoder         : Lavf58.29.100
  Duration: 01:08:19.27, start: 0.011995, bitrate: 32 kb/s
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 32 kb/s
    Metadata:
      encoder         : Lavf

为什么持续时间减少了 0.03 秒?为什么开始时间不再是 0?另外,为什么当我在 vlc 中打开此文件时,它似乎无法确定持续时间?对于原始文件,它可以立即知道持续时间。但对于新文件,它似乎在尝试估计它,随着我播放它,它随着时间的推移慢慢接近它。

vlc 中的编解码器信息(两个文件的编解码器信息相同)

Stream 0
    Codec: MPEG Audio layer 1/2 (mpga)
    Type: Audio
    Channels: Stereo
    Sample rate: 44100 Hz
    Bits per sample: 32
    Bitrate: 32 kb/s

答案1

MP3 文件不具备与 MP4 或 MKV 文件相同的内部结构 – “普通”MP3 只是一系列原始的音频帧,其持续时间并未存储在任何地方。对于恒定比特率 MP3 文件,持续时间可以根据文件长度计算,而对于 VBR,只能通过逐帧评估整个文件来确定。

那是,除非编码器将持续时间和 VBR 信息存储在“LAME INFO 标签“(又名“Xing VBR 标签”)。现在,几乎所有编码器和播放器都支持此标签,并且大多数 MP3 文件都具有该标签。

从 ffprobe 输出来看,它看起来像你的原始文件没有有这样的标签,而新文件有(“编码器:Lavf”是其中的一部分,由 FFmpeg 添加)。所以我期望得到相反的结果——新文件的持续时间应该是已知的,但原始文件的持续时间则不是——也就是说,除非 FFmpeg 添加了不准确的信息。


事实上,普通的 MP3 文件甚至没有为元数据保留任何空间——Xing 和 ID3 标签实际上伪装成大多数解码器都知道要忽略的特殊音频帧——这也意味着 MP3 文件的估计时长可能取决于它包含或曾经包含的元数据量。如果文件在删除 ID3v2 标签后留下了空洞,那么“大小÷比特率”这样的简单估计将是错误的。

您可以使用Mp3诊断查看文件的结构。(它还可用于修复不准确的 Xing 标签,这些标签会使玩家认为曲目比实际更长或更短。)

答案2

mp3 文件包含三部分:音频块、元数据和垃圾。音频播放器可能具有读取和显示元数据的代码,并且它必须有播放音频块的代码。无用的东西会被忽略。

现在显示音频数据的长度发生了变化。可能有两个原因:

  1. 元数据编辑器成功破坏了音频块的头部(音频块通常约为 30ms)。头部被破坏后,音频块就成了垃圾,因此这实际上缩短了音频长度。

  2. 音频播放器不会扫描所有音频块并累加它们的持续时间,而是根据文件大小猜测音频块的数量。而且它可能没有考虑元数据,因此元数据越多,音频长度就越高。由于您删除了元数据,估计的音频长度减少了。实际长度没有变化,可能比显示的长度要短。

相关内容