Reference
- ID3
- ID3v1
- ID3v2.3.0
- ID3v2.4.0-changes
- MPEG Audio Layer I/II/III frame header
- MP3文件解析详解
- MP3 File Structure
- The LAME Project
基本结构
简介
当您听音乐时,ID3 标签提供标题、艺术家、年份、流派和其他重要信息。在这里您可以找到当前的标准文件;指向几乎所有语言的软件库的指针以及可用于增强 MP3 音频库的其他信息。
ID3 标签是 MP3 文件的音频文件数据标准,被世界各地的软件和硬件开发人员积极使用。 ID3 标签在 iTunes、Windows Media Player、Winamp、VLC 等软件以及 iPod、Creative Zen、Samsung Galaxy 和 Sony Walkman 等硬件播放器中受支持。
ID3 标签是以规定格式存储的 MP3 音频文件中的数据容器。此数据通常包含当前音频文件的艺术家姓名、歌曲名称、年份和流派。该网站包含 ID3 标记数据容器的格式标准信息。如果您已经读到这里并且感到困惑,请查看 ID3v2Easy 页面以获取简短的低技术介绍。
虽然 ID3 标签有旧的和未来的标准,但今天实施的最流行的版本是 ID3 2.3 版。此网站上记录了后续版本 2.4,但由于对某些修订的一些分歧以及软件和硬件市场中存在的巨大惯性,因此尚未获得流行状态。
消费者应阅读介绍,其中介绍了 ID3 标记格式的基础知识及其历史。该页面上提供了有关 ID3 标签如何工作的基本技术信息的链接。常见问题 (FAQ) 页面包含一些其他感兴趣的项目。
不熟悉 ID3 标签格式的开发人员可能希望直接跳转到 ID3v2 made easy 页面以进行快速的低技术介绍。那些有兴趣深入了解标准的人应该查看开发人员信息页面。软件开发人员将在实现下找到 ID3 标签操作库。
ID3 标记的技术方面在 ID3v2 开发人员邮件列表中讨论。
ID3v1
音频格式 MPEG 层 I、层 II 和层 III (MP3) 没有保存内容信息的本地方式,除了一些简单的是/否参数,如“私有”、“受版权保护”和“原始家庭”(意思是这个是原始文件而不是副本)。1996 年,Eric Kemp 别名 NamkraD 使用程序“Studio3”引入了这个问题的解决方案。通过在文件末尾添加一小块额外数据,可以让 MP3 文件携带有关音频的信息,而不仅仅是音频本身。
标签的位置,正如数据所称的那样,可能是因为它干扰解码器的可能性很小。为了便于检测,选择了 128 字节的固定大小。该标签具有以下布局(如右侧方案所示):
Field | Length | Contents |
---|---|---|
ID3v1 tag | 3 | TAG |
Title | 30 | Song Name |
Artist | 30 | Artist |
Album | 30 | Album Name |
Year | 4 | Year |
Comment | 30 | Comment |
Genre | 1 | Song Genre Identifier |
ID3v2
tag
是本文档中描述的整个标签。tag
包括tag header
、tag body
(1个或n个frame
)、可选的padding
。
frame
是tag
中的信息块。frame
包括frame header
、frame body
(1个或n个field
)。
field
是一条实际信息。
ID3v2 中的位顺序是最高有效位在前(MSB)。
多字节数字中的字节顺序是最重要的字节优先(例如,0x12345678 将被编码为 0x12 34 56 78),也就是大端存储。
ID3v2.3.0
tag header
ID3v2 header
Field | Length | Contents |
---|---|---|
ID3v2/file identifier | 3 | ID3 |
ID3v2 version | 2 | 03 00(16进制) |
ID3v2 flags | 1 | abc00000(2进制) |
ID3v2 size | 4 | 4 * 0xxxxxxx(2进制) |
1、ID3v2/file identifier
前三个字节总是ID3
,表示这是一个ID3v2 tag
,后面紧跟两个版本字节。
2、ID3v2 version
ID3v2 version
的第一个字节是它的主要版本,而第二个字节是它的修订号。在这种情况下,这是 ID3v2.3.0。所有修订版都向后兼容,而主要版本则不然。如果支持 ID3v2.2.0 及以下版本的软件遇到版本 3 或更高版本,则应简单地忽略整个tag
。版本和修订永远不会是 0xFF。
3、ID3v2 flags
ID3v2 version
跟一个ID3v2 flags
,目前只使用了3个flags
:
- a -
Unsynchronisation
ID3v2 flags
中的第 7 位指示是否使用了unsynchronisation
。 - b -
Extended header
ID3v2 flags
中的第 6 位指示header
后面是否有extended header
。 - c -
Experimental indicator
ID3v2 flags
中的第 5 位应用作“实验指示符”。
应清除所有其他flags
。如果设置了这些未定义flags
之一,则可能意味着该tag
对于不知道flags
函数的解析器是不可读的。
4、ID3v2 size
ID3v2 size
用四个字节编码,其中每个字节的最高有效位(第 7 位)设置为零,总共 28 位。零位被忽略,因此 257 字节长的标签表示为 0x00 00 02 01。
ID3v2 size
是unsychronisation
后完整tag
的大小,包括padding
,不包括header
但不排除extended header
(tag
总大小 - 10)。大小描述中仅使用 28 位(最多代表 256MB)以避免引入“假同步信号”。
可以使用以下模式检测ID3v2 tag
:
其中 yy 小于 0xFF,xx 是flags
字节,zz 小于 0x80。
ID3v2 extended header
extended header
包含对正确解析tag
信息不重要的信息,因此extended header
是可选的。extended header
被认为与header
本身是分开的,因此会受到unsynchronisation
的影响。
Field | Length | Contents |
---|---|---|
extended header size | 4 | xx xx xx xx(16进制) |
extended flags | 2 | xx xx(16进制) |
size of padding | 4 | xx xx xx xx(16进制) |
1、extended header size
extended header size
(当前为 6 或 10 个字节)不包括自身。
2、extended flags
extended flags
是描述tag
进一步属性的辅助标志集。这些属性目前定义如下:
- x - 存在 CRC 数据
如果设置了此flag
,则将 CRC-32 数据的四个字节附加到extended header
。CRC 应在extended header
和padding
之间的数据unsynchronisation
之前计算。1Total frame CRC xx xx xx xx(16进制)
3、size of padding
size of padding
只是不包括frame
和header
的tag
总大小,即padding
。
frame
frame header
frame header
的布局:
Field | Length | Contents |
---|---|---|
frame ID | 4 | xx xx xx xx(16进制) |
size | 4 | xx xx xx xx(16进制) |
flags | 2 | xx xx(16进制) |
1、frame ID
由字符大写 A-Z 和 0-9 组成的frame ID
。以X、Y、Z
开头的frame ID
是实验用的,大家自由使用,不需要在tag header
中设置实验位。请记住,其他人可能使用了与您相同的frame ID
。所有其他frame ID
要么被使用,要么被保留以备将来使用。
已声明的frame ID
:
frame ID | Contents |
---|---|
AENC | [#sec4.20 Audio encryption] |
APIC | [#sec4.15 Attached picture] |
COMM | [#sec4.11 Comments] |
COMR | [#sec4.25 Commercial frame] |
ENCR | [#sec4.26 Encryption method registration] |
EQUA | [#sec4.13 Equalization] |
ETCO | [#sec4.6 Event timing codes] |
GEOB | [#sec4.16 General encapsulated object] |
GRID | [#sec4.27 Group identification registration] |
IPLS | [#sec4.4 Involved people list] |
LINK | [#sec4.21 Linked information] |
MCDI | [#sec4.5 Music CD identifier] |
MLLT | [#sec4.7 MPEG location lookup table] |
OWNE | [#sec4.24 Ownership frame] |
PRIV | [#sec4.28 Private frame] |
PCNT | [#sec4.17 Play counter] |
POPM | [#sec4.18 Popularimeter] |
POSS | [#sec4.22 Position synchronisation frame] |
RBUF | [#sec4.19 Recommended buffer size] |
RVAD | [#sec4.12 Relative volume adjustment] |
RVRB | [#sec4.14 Reverb] |
SYLT | [#sec4.10 Synchronized lyric/text] |
SYTC | [#sec4.8 Synchronized tempo codes] |
TALB | [#TALB Album/Movie/Show title] |
TBPM | [#TBPM BPM (beats per minute)] |
TCOM | [#TCOM Composer] |
TCON | [#TCON Content type] |
TCOP | [#TCOP Copyright message] |
TDAT | [#TDAT Date] |
TDLY | [#TDLY Playlist delay] |
TENC | [#TENC Encoded by] |
TEXT | [#TEXT Lyricist/Text writer] |
TFLT | [#TFLT File type] |
TIME | [#TIME Time] |
TIT1 | [#TIT1 Content group description] |
TIT2 | [#TIT2 Title/songname/content description] |
TIT3 | [#TIT3 Subtitle/Description refinement] |
TKEY | [#TKEY Initial key] |
TLAN | [#TLAN Language(s)] |
TLEN | [#TLEN Length] |
TMED | [#TMED Media type] |
TOAL | [#TOAL Original album/movie/show title] |
TOFN | [#TOFN Original filename] |
TOLY | [#TOLY Original lyricist(s)/text writer(s)] |
TOPE | [#TOPE Original artist(s)/performer(s)] |
TORY | [#TORY Original release year] |
TOWN | [#TOWN File owner/licensee] |
TPE1 | [#TPE1 Lead performer(s)/Soloist(s)] |
TPE2 | [#TPE2 Band/orchestra/accompaniment] |
TPE3 | [#TPE3 Conductor/performer refinement] |
TPE4 | [#TPE4 Interpreted, remixed, or otherwise modified by] |
TPOS | [#TPOS Part of a set] |
TPUB | [#TPUB Publisher] |
TRCK | [#TRCK Track number/Position in set] |
TRDA | [#TRDA Recording dates] |
TRSN | [#TRSN Internet radio station name] |
TRSO | [#TRSO Internet radio station owner] |
TSIZ | [#TSIZ Size] |
TSRC | [#TSRC ISRC (international standard recording code)] |
TSSE | [#TSEE Software/Hardware and settings used for encoding] |
TYER | [#TYER Year] |
TXXX | [#TXXX User defined text information frame] |
UFID | [#sec4.1 Unique file identifier] |
USER | [#sec4.23 Terms of use] |
USLT | [#sec4.9 Unsychronized lyric/text transcription] |
WCOM | [#WCOM Commercial information] |
WCOP | [#WCOP Copyright/Legal information] |
WOAF | [#WOAF Official audio file webpage] |
WOAR | [#WOAR Official artist/performer webpage] |
WOAS | [#WOAS Official audio source webpage] |
WORS | [#WORS Official internet radio station homepage] |
WPAY | [#WPAY Payment] |
WPUB | [#WPUB Publishers official webpage] |
WXXX | [#WXXX User defined URL link frame] |
2、size
frame ID
后跟一个size
,使每个frame
的header
总大小为 10 个字节。size
计算为不包括frame header
(frame size
- 10)。
3、flags
在frame header
中,size
描述符后跟两个flags
字节。
frame
在tag
中的出现没有固定的顺序,尽管希望frame
按照与文件识别相关的重要性顺序排列。此类顺序的示例:UFID
、TIT2
、MCDI
、TRCK
…
一个tag
必须至少包含一个frame
。一个frame
必须至少有 1 个字节大,不包括header
。
如果没有其他说明,则字符串表示为 0x20 - 0xFF 范围内的 ISO-8859-1 字符。此类字符串在frame
描述中表示为 <text string> 或 <full text string>(如果允许换行)。所有 Unicode 字符串都使用 16 位 unicode 2.0(ISO/IEC 10646-1:1993,UCS-2)。Unicode 字符串必须以 Unicode BOM(0xFF FE 或 0xFE FF)开头以标识字节顺序。
所有数字字符串和 URL 始终编码为 ISO-8859-1。如果使用 ISO-8859-1 编码,则终止的字符串以 0x00 结尾,如果编码为 unicode,则以 0x00 00 结尾。如果没有其他说明,则禁止换行符。在 ISO-8859-1 中,当允许时,仅用 0x0A 表示一个新行。允许不同类型文本编码的frame
在Size
之后直接有一个文本编码描述字节。如果使用 ISO-8859-1,则此字节应为 0x00,如果使用 Unicode,则应为 0x01。如果允许换行,则依赖于编码的字符串表示为 <根据编码的文本字符串> 或 <根据编码的全文字符串>。任何以 NULL 结尾的空 Unicode 字符串都可以具有 Unicode BOM 后跟一个 Unicode NULL(0xFF FE 00 00 或 0xFE FF 00 00)。
根据 ISO-639-2,三字节语言字段用于描述frame
内容的语言。
所有 URL 都可以是相对的,例如“图片.png”,“../doc.txt”。
如果一个frame
比它应该长,例如具有比本文档中指定的更多的字段,这表明在 ID3v2 标准的更高版本中对frame
进行了添加。这由标记标题中的修订号反映。
在frame header
中,Size
描述符后跟两个flags
字节。必须清除所有未使用的标志。第一个字节用于“状态消息”,第二个字节用于编码目的。如果在第一个字节中设置了未知flag
,则在未清除该位的情况下,可能无法更改frame
。如果在第二个字节中设置了未知flag
,则可能无法读取。flags
字段定义如下:
- a -
tag
改变保存
如果该frame
未知且tag
以任何方式更改,该flag
会告诉软件如何处理该frame
。这适用于各种更改,包括添加更多padding
和重新排序frame
。- 0:
frame
应该被保留。 - 1:
frame
应该被丢弃。
- 0:
- b - 文件更改保存
如果该frame
未知并且不包括tag
的文件被更改,则该flag
告诉软件如何处理该frame
。当音频完全被其他音频数据替换时,这不适用。- 0:
frame
应该被保留。 - 1:
frame
应该被丢弃。
- 0:
- c - 只读
这个flag
,如果设置,告诉软件这个frame
的内容是只读的。更改内容可能会破坏某些内容,例如一个签名。如果内容被改变,不知道为什么frame
被标记为只读并且没有采取适当的方法来补偿,例如重新计算签名,该位应该被清除。 - i - 压缩
该flag
指示frame
是否被压缩。- 0:
frame
未压缩。 - 1:
frame
使用 [#ZLIB zlib] 压缩,其中 4 个字节用于附加到frame header
的decompressed size
。
- 0:
- j - 加密
此flag
指示frame
是否已加密。如果设置一个字节,指示它是用哪种方法加密的,则将附加到frame header
。见第 4.26 节。有关加密方法注册的更多信息。- 0:
frame
未加密。 - 1:
frame
被加密。
- 0:
- k - 分组标识
该flag
指示该frame
是否与其他frame
属于一个组。如果设置,则将组标识符字节添加到frame header
。具有相同组标识符的每个frame
都属于同一组。- 0:
frame
不包含组信息。 - 1:
frame
包含组信息。
- 0:
一些flags
表明frame header
扩展了附加信息。该信息将按照与指示添加的flags
相同的顺序添加到frame header
中。例如,解压缩大小的四个字节将在加密方法字节之前。这些添加到frame header
的内容虽然不包含在frame header Size
中但包含在frame size
字段中,但不受加密或压缩的影响。
field
field
可以是一个值,一个字符串等。一个数字字符串是一个只包含字符 0-9 的字符串。
padding
允许在最后一个frame
(在 ID3 tag
的末尾)之后包含padding
,使所有frame
的大小加在一起小于tag header
给出的大小。
这种padding
的一个可能目的是允许在tag
内添加一些额外的frame
或放大现有的frame
,而不必重写整个文件。
padding
字节的值必须为 0x00。
ID3v2.4.0
ID3v2.4.0 是 ID3v2.3.0 的修订版,是一个非正式标准。
tag
在文件中的位置以及查找和合并tag
的方法在 ID3v2.4.0 [S:5] 中比以前的版本更好地定义。添加tag footer
[S:3.4] 改进了对tag
的反向搜索。tag footer
标志已添加到header
标志以指示 ID3v2 footer
的存在,因此大小字段不受footer
[S:3.1] 的影响。
extended header
已完全重写 [S:3.2] 并且不会产生假同步。还可以在extended header
中指示人工标记限制,以用于瘦客户端。
unsynchronisation
[S:6.1] 是在frame
级别完成的,而不是在tag
级别,这使得跳过frame
更容易,增加了tag
的可流性。header
[S:3.1]中的unsynchronisation
标志表示是否所有frame
都已不同步,而frame header
[S:4.1.2]中的新unsynchronisation
标志表示unsynchronisation
。为了避免frame header
中的假同步,大小描述和标志字段已被重写 [S:4]。当frame header
中的unsynchronisation
标志被设置时,完整tag
的重新同步可能会导致损坏的tag
。
字符编码 UTF-16BE 和 UTF-8 已添加到有效编码列表 [S:4]。
已弃用的frame
:
frame ID | Contents |
---|---|
EQUA | Equalization This frame is replaced by the EQU2 frame, ‘Equalisation (2)’[F:4.12]. |
IPLS | Involved people list This frame is replaced by the two frames TMCL, ‘Musician credits list’ [F:4.2.2], and TIPL, ‘Involved people list’ [F:4.2.2]. |
RVAD | Relative volume adjustment This frame is replaced by the RVA2 frame, ‘Relative volume adjustment (2)’ [F:4.11]. |
TDAT | Date This frame is replaced by the TDRC frame, ‘Recording time’[F:4.2.5]. |
TIME | Time This frame is replaced by the TDRC frame, ‘Recording time’[F:4.2.5]. |
TORY | Original release year This frame is replaced by the TDOR frame, ‘Original release time’[F:4.2.5]. |
TRDA | Recording dates This frame is replaced by the TDRC frame, ‘Recording time’[F:4.2.5]. |
TSIZ | Size The information contained in this frame is in the general case either trivial to calculate for the player or impossible for the tagger to calculate. There is however no good use for such information. The frame is therefore completely deprecated. |
TYER | Year This frame is replaced by the TDRC frame, ‘Recording time’[F:4.2.5]. |
新frame
:
frame ID | Contents |
---|---|
ASPI | Audio seek point index [F:4.30] |
EQU2 | Equalisation (2) [F:4.12] |
RVA2 | Relative volume adjustment (2) [F:4.11] |
SEEK | Seek frame [F:4.29] |
SIGN | Signature frame [F:4.28] |
TDEN | Encoding time [F:4.2.5] |
TDOR | Original release time [F:4.2.5] |
TDRC | Recording time [F:4.2.5] |
TDRL | Release time [F:4.2.5] |
TDTG | Tagging time [F:4.2.5] |
TIPL | Involved people list [F:4.2.2] |
TMCL | Musician credits list [F:4.2.2] |
TMOO | Mood [F:4.2.3] |
TPRO | Produced notice [F:4.2.4] |
TSOA | Album sort order [F:4.2.5] |
TSOP | Performer sort order [F:4.2.5] |
TSOT | Title sort order [F:4.2.5] |
TSST | Set subtitle [F:4.2.1] |
数据帧
在 MPEG 音频文件中,没有主header
,因为 MPEG 音频文件只是由一系列称为帧的较小部分组成。每个帧都是一个数据块,具有自己的header
和音频信息。
在层 I 或层 II 的情况下,帧之间是完全独立的,因此您可以剪切 MPEG 音频文件的任何部分并正确播放。然后播放器将从它找到的第一个完整的有效帧开始播放音乐。但是,在层 III 的情况下,帧并不总是独立的。由于可能使用“字节存储库”,它是一种内部缓冲区,帧通常相互依赖。在最坏的情况下,可能需要 9 个输入帧才能解码一帧。
如果您需要检索有关 MPEG 音频文件的信息,您可以简单地定位第一帧,并从其标题中检索信息。其他帧中的信息应与第一个帧一致,但比特率除外,因为您可能正在从可变比特率 (VBR) 文件中检索信息。在 VBR 文件中,可以在每一帧中更改比特率。例如,它可以用来在整个文件中保持恒定的音质,当音乐更复杂时使用更多位,因此需要更多位以类似的质量进行编码。
frame header
frame header
本身的长度为 32 位(4 字节)。frame header
的前 12 位(或在 MPEG-2.5 扩展情况下的前 11 位)始终设置为 1,称为“帧同步”。
以下是frame header
中内容的详细信息:
Field | Length(bits) | Contents |
---|---|---|
Frame synchronizer | 11 | 所有位均为1 |
MPEG Audio version ID | 2 | 00 = MPEG-2.5 01 = reserved 10 = MPEG-2 (ISO/IEC 13818-3) 11 = MPEG-1 (ISO/IEC 11172-3) 注意:MPEG-2.5 版是最近添加到 MPEG-2 标准中的。它是用于极低比特率文件的扩展,允许使用较低的采样频率。如果您的解码器不支持此扩展,建议您使用 12 位进行同步,而不是 11 位。 |
Layer description | 2 | 00 = reserved 01 = Layer III 10 = Layer II 11 = Layer I |
Protection bit | 1 | 0 = Protected by CRC (16bit CRC follows header) 1 = Not protected |
Bitrate index | 4 | |
Sampling rate frequency index | 2 | |
Padding bit | 1 | 0 = frame is not padded 1 = frame is padded with one extra slot 填充用于精确匹配比特率。例如:128kbps 44.1kHz 层 II 使用大量 418 字节和一些 417 字节长的帧来获得精确的 128k 比特率。对于层 I 时隙为 32 位长,对于层 II 和层 III 时隙为 8 位长。 |
Private bit | 1 | 这只是提供信息。 |
Channel Mode | 2 | 00 = Stereo 01 = Joint stereo (Stereo) 10 = Dual channel (2 mono channels) 11 = Single channel (Mono) 注意:双声道文件由两个独立的单声道组成。每个都使用文件比特率的一半。大多数解码器将它们输出为立体声,但情况可能并非总是如此。一个使用示例是在同一位流中承载两种不同语言的一些语音,然后适当的解码器将仅解码所选语言。 |
Mode extension | 2 | 仅用于 Joint stereo 模式扩展用于加入对 stereo 效果无用的信息,从而减少所需的比特。这些位由编码器在 Joint stereo 模式下动态确定,Joint stereo 可以从一帧更改为另一帧,甚至可以打开或关闭。 MPEG 文件的完整频率范围被划分为子带,共有 32 个子带。对于层 I 和 II,这两个位确定应用 intensity stereo 的频率范围(频带)。对于层 III,这两位决定使用哪种类型的 Joint stereo(intensity stereo or m/s stereo)。频率范围在解压算法中确定。 |
Copyright | 1 | 0 = Audio is not copyrighted 1 = Audio is copyrighted 版权与 CD 和 DAT 磁带上的版权位具有相同的含义,即如果设置了该位,则表明复制内容是非法的。 |
Original | 1 | 0 = Copy of original media 1 = Original media 原始位表示,如果它被设置,则该帧位于其原始媒体上。 |
Emphasis | 2 | 00 = none 01 = 50/15 ms 10 = reserved 11 = CCIT J.17 强调指示在这里告诉解码器必须去强调文件,即解码器必须在类似杜比的噪声抑制之后“重新均衡”声音。它很少使用。 |
1、Bitrate index
bits | MPEG-1,层 I | MPEG-1,层 II | MPEG-1,层 III | MPEG-2,层 I | MPEG-2 & MPEG-2.5,层 II & 层 III |
---|---|---|---|---|---|
0000 | free | free | free | free | free |
0001 | 32 | 32 | 32 | 32 | 8 |
0010 | 64 | 48 | 40 | 48 | 16 |
0011 | 96 | 56 | 48 | 56 | 24 |
0100 | 128 | 64 | 56 | 64 | 32 |
0101 | 160 | 80 | 64 | 80 | 40 |
0110 | 192 | 96 | 80 | 96 | 48 |
0111 | 224 | 112 | 96 | 112 | 56 |
1000 | 256 | 128 | 112 | 128 | 64 |
1001 | 288 | 160 | 128 | 144 | 80 |
1010 | 320 | 192 | 160 | 160 | 96 |
1011 | 352 | 224 | 192 | 176 | 112 |
1100 | 384 | 256 | 224 | 192 | 128 |
1101 | 416 | 320 | 256 | 224 | 144 |
1110 | 448 | 384 | 320 | 256 | 160 |
1111 | bad | bad | bad | bad | bad |
注意:所有值均以 kbps 为单位。
“free”是指 free 格式。free 比特率必须保持不变,并且必须低于允许的最大比特率。解码器不需要支持 free 比特率流的解码。
“bad”是指该值是不允许的。
MPEG 文件可能具有可变比特率(VBR)。然后可以使用不同的比特率创建每个帧。它可以用于所有层。层 III 解码器必须支持这种方法。层 I 和层 II 解码器可能支持它。
对于层 II,有些比特率和模式的组合是不允许的。这是允许的组合列表:
bitrate | single channel | stereo | intensity stereo | dual channel |
---|---|---|---|---|
free | yes | yes | yes | yes |
32 | yes | no | no | no |
48 | yes | no | no | no |
56 | yes | no | no | no |
64 | yes | yes | yes | yes |
80 | yes | no | no | no |
96 | yes | yes | yes | yes |
112 | yes | yes | yes | yes |
128 | yes | yes | yes | yes |
160 | yes | yes | yes | yes |
192 | yes | yes | yes | yes |
224 | no | yes | yes | yes |
256 | no | yes | yes | yes |
320 | no | yes | yes | yes |
384 | no | yes | yes | yes |
可变比特率(VBR):
该系统的创建是为了最大限度地减少文件长度并保持音质。
较高的频率通常需要更多的编码空间(这就是为什么许多编解码器将所有频率都削减到 cca 16kHz 以上的原因)而较低的音调需要更少的空间。因此,如果歌曲的某些部分不包含更高的音调,那么使用 192kbps 就是浪费空间。仅使用 96kbps 就足够了。
这就是VBR的原理。编解码器查看帧,然后选择适合其音质的比特率。
这听起来很完美,但它带来了一些问题:
如果您想在歌曲中跳过 2 分钟,固定比特率(CBR)不是问题,因为您可以简单地计算跳过所需的字节数。但是用 VBR 是不可能的。帧长度应该是任意的,因此您必须逐帧进行计数(耗时且非常不切实际)或使用另一种机制进行近似计数。
如果你想从 VBR 文件的中间剪掉 5 分钟(我们所知道的 CD,最后一首歌需要 10 分钟,但 5 分钟是纯粹的沉默,地狱!)问题是一样的。
结果? VBR 文件更难控制和调整。而且我不喜欢感觉音质每时每刻都在变化。而且 AFAIK 许多编解码器在创建高质量的 VBR 时存在问题。
就我个人而言,我看不出为什么要使用 VBR - 如果 MP3 中的一张 CD 的大小是 55 MB 的 CBR 或 51 MB 的 VBR,我不会在乎。但每个人都有不同的品味……有些人更喜欢 VBR。
VBR 文件结构:
与 CBR 相同。但第一帧不包含音频数据,它用于有关 VBR 文件的特殊信息。
2、Sampling rate frequency index
bits | MPEG1 | MPEG2 | MPEG2.5 |
---|---|---|---|
00 | 44100 Hz | 22050 Hz | 11025 Hz |
01 | 48000 Hz | 24000 Hz | 12000 Hz |
10 | 32000 Hz | 16000 Hz | 8000 Hz |
11 | reserv. | reserv. | reserv. |
3、Mode extension
Layer I and II
value | Layer I & II |
---|---|
00 | bands 4 to 31 |
01 | bands 8 to 31 |
10 | bands 12 to 31 |
11 | bands 16 to 31 |
Layer III
Intensity stereo | MS stereo |
---|---|
off | off |
on | off |
off | on |
on | on |
CRC checksum
帧还可能具有可选的 CRC 校验和。它有 16 位长,如果存在,则紧跟在frame header
之后。CRC 之后是音频数据。通过重新计算 CRC 并将其值与 sored
值进行比较,您可以检查帧在比特流传输期间是否已更改。
frame body
MPEG 规范中规定的不同层中每帧的采样点的个数:
MPEG-1 | MPEG-2 | MPEG-2.5 | |
---|---|---|---|
Layer I | 384 | 384 | 384 |
Layer II | 1152 | 1152 | 1152 |
Layer III | 1152 | 576 | 576 |
第一帧结构:
Field | Length | Contents |
---|---|---|
frame header | 4 | |
not used | n | |
VBR file identifier | 4 | Xing 如果没有找到,文件应该是 CBR。 |
Flags | 4 | 决定了是否包含后面的某个 field 1 = Frames 2 = Bytes 4 = TOC(Table of Contents) 8 = VBR Scale 所有值可以同时存储。 |
Frames | 4 | 文件中的帧数(包括第一帧) |
Bytes | 4 | 以字节为单位的文件长度 |
TOC(Table of Contents) | 100 | 包含 100 个索引(一个字节长度)以便于在文件中查找。大致解决了在文件内部移动的问题。 根据此公式,每个字节都有一个值: (TOC[i] / 256) x fileLenInBytes 所以如果音频持续 240 秒,且文件长度为 5000000 字节,如果你想跳到 60 秒:(TOC[(60 / 240)] / 256) x 5000000 如果您想修剪 VBR 文件,您还应该正确重建 Frames 、Bytes 和TOC 。 |
VBR Scale | 4 |
MP3 编码格式
LAME
是在 LGPL 下获得许可的高质量 MPEG 音频 Layer III (MP3) 编码器。
今天,LAME
被认为是中高比特率和 VBR 的最佳 MP3 编码器,这主要归功于其开发人员的专注工作和开源许可模式,使该项目能够利用来自世界各地的工程资源。质量和速度的改进仍在发生,可能使 LAME
成为唯一仍在积极开发的 MP3 编码器。
LAME header
Field | Length(bits) | Contents |
---|---|---|
Encoder short VersionString | 9 | LAME 版本 |
Info Tag revision + VBR method | 1 | 高4位表示Info Tag revision ,修订号:0 ~ 14 = rev0 ~ rev14 15 = reserved 低4位表示 VBR method :0 = unknown 1 = constant bitrate 2 = abr 3 = vbr old / vbr rh 4 = vbr mtrh 5 = vbr mt 6 = full VBR method4 8 = constant bitrate 2 pass 9 = abr 2 pass 15 = reserved |
Lowpass filter value | 1 | 0 = unknown 1 ~ 255 = 100 ~ 25500Hz |
Peak signal amplitude | 4 | 以解码格式存储的最大信号幅度。 0 = unknown |
Radio Replay Gain | 2 | 需要使所有音轨的响度相等。 第1~3位表示NAME of Gain adjustment: 000 = not set 001 = ratio 010 = audiophile 第4~6位表示ORIGINATOR of Gain adjustment: 000 = not set 001 = set by artist 010 = set by user 011 = set by my model 100 = set by simple RMS average 第7位表示符号位 第8~16位表示ABSOLUTE GAIN ADJUSTMENT,存储 10 倍的调整(以提供额外的小数位)。 |
Audiophile Replay Gain | 2 | 需要提供理想的聆听响度。 第1~3位表示NAME of Gain adjustment: 000 = not set 001 = ratio 010 = audiophile 第4~6位表示ORIGINATOR of Gain adjustment: 000 = not set 001 = set by artist 010 = set by user 011 = set by my model 100 = set by simple RMS average 第7位表示符号位 第8~16位表示ABSOLUTE GAIN ADJUSTMENT,存储 10 倍的调整(以提供额外的小数位)。 |
Encoding flags + ATH Type | 1 | 高4位表示Encoding flags 低4位表示 ATH Type |
if ABR {specified bitrate} else {minimal bitrate} | 1 | IF the file is an ABR file:0 = unknown 1 ~ 255 = 1 ~ 255 kbit/s or larger(–abr 1 ~ 255) IF the file is NOT an ABR file: (CBR/VBR )the ( CBR )/(minimal VBR (-b)) bitrate is stored here 8-255. 255 if bigger. |
Encoder delays | 3 | 前12位的值(0 ~ 4095)表示采样数,后12位的值(0 ~ 4095)表示用于完成最后一帧的0采样。 |
Misc | 1 | 第1~2位表示添加的不同噪声形状: 00 = noise shaping 0 01 = noise shaping 1 10 = noise shaping 2 11 = noise shaping 3 第3~5位表示立体声模式: 000 = (m)ono 001 = (s)tereo 010 = (d)ual 011 = (j)oint 100 = (f)orce 101 = (a)uto 110 = (i)ntensity 111 = (x)undefined / different 第6位表示是否使用了不明智的设置: 0 = no 1 = yes 第7~8位表示源(非 mp3)采样频率: 00 = 32kHz or smaller 01 = 44.1kHz 10 = 48kHz 11 = higher than 48kHz |
MP3 Gain | 1 | 任何 mp3 都可以通过像这样的工具以无损方式放大 2 ^ ( x * 0.25) 倍。 x 为 00 ~ ff = -127 ~ 127 |
Preset and surround info | 2 | 第1~2位未使用 第3~4位表示环绕声信息: 0 = 无环绕声信息 1 = DPL编码 2 = DPL2编码 3 = 环绕声编码 8 = reserved 第5~16位表示 Preset :0 = unknown/no preset used 这允许 2047 个预设范围。对于 Lame,我们将使用内部预设枚举的值。 |
MusicLength | 4 | 包含最初由 LAME 制作的 mp3 文件的确切长度(以字节为单位)的 32 位整数字段,末尾排除了 ID3 标签信息。它计算的第一个字节是这个 LAME 标签的第一个字节,它计算的最后一个字节是包含音乐的最后一个 mp3 帧的最后一个字节。00000000 ~ ffffffff = 0 ~ 4294967295,大约是 27.79 小时的 44.1kHz 320kbit/s 音乐。 |
MusicCRC | 2 | 包含原始由 LAME 制作的完整 mp3 音乐数据的 CRC-16。 |
CRC-16 of Info Tag | 2 | 包含信息头帧的前面所有数据的 CRC-16,也就是从frame header 开始到该field之前的所有数据。完成所有其他字段后,将在最后计算此字段。 原因:保护 LAME VBR header 免受轻易篡改。 |
1、Encoding flags
2进制 | Contents |
---|---|
000? | LAME uses “–nspsytune”, ? = 0 : false ? = 1 : true |
00?0 | LAME uses “–nssafejoint” ? = 0 : false ? = 1 : true |
0?00 | This track is –nogap continued in a next track ? = 0 : false ? = 1 : true is true for all but the last track in a –nogap album |
?000 | This track is the –nogap continuation of an earlier one ? = 0 : false ? = 1 : true is true for all but the first track in a –nogap album |
demo
解析 MP3 文件,分析 MP3 封装格式。
文件流转16进制的源代码
|
|
demo1
CLAP.mp3,没有ID3,只有数据帧。
转换结果
|
|
分析
frame header
第1~4字节:
0xff fb 94 04 = 11111111 11111011 10010100 00000100b
Field | Length | 2进制 | Contents |
---|---|---|---|
Frame sync | 11 | 11111111111 | |
MPEG Audio version ID | 2 | 11 | MPEG-1 |
Layer description | 2 | 01 | Layer III |
Protection bit | 1 | 1 | Not protected |
Bitrate index | 4 | 1001 | 128 kbps |
Sampling rate frequency index | 2 | 01 | 48000 Hz |
Padding bit | 1 | 0 | frame is not padded |
Private bit | 1 | 0 | |
Channel Mode | 2 | 00 | Stereo |
Mode extension | 2 | 00 | |
Copyright | 1 | 0 | Audio is not copyrighted |
Original | 1 | 1 | Original media |
Emphasis | 2 | 00 | none |
frame body
第5~156字节:
Field | Length | 16进制 | Contents | 所在行号 |
---|---|---|---|---|
not used | n | 全是00 | 00000001 ~ 00000003 | |
VBR file identifier | 4 | 58 69 6e 67 | Xing |
00000003 |
Flags | 4 | 00 00 00 0f | 0x0000000f = 1+2+4+8, 也就是后面的4个 field 都存在 |
00000003 |
Frames | 4 | 00 00 00 4d | 0x0000004d = 77个数据帧 | 00000003 |
Bytes | 4 | 00 00 4b 90 | 0x00004b90 = 19344B = 18.890625KB | 00000004 |
TOC(Table of Contents) | 100 | 00 0c 19 22 2a 2a 35 3f 47 47 4f 55 5a 5f 5f 63 67 69 69 6b 6d 6e 6e 70 71 73 74 74 76 77 79 79 7b 7d 7e 7e 80 81 82 84 84 85 87 89 89 8b 8c 8e 8e 90 92 94 96 96 97 9a 9c 9c 9f a1 a4 a4 a6 a9 ac af af b2 b5 b8 b8 ba be c0 c0 c4 c7 ca cd cd d1 d4 d6 d6 da dd e1 e1 e4 e7 eb ee ee f1 f4 f7 f7 fb fe ff | 77个数据帧平均分成100份,每份是一个索引 | 00000004 ~ 00000010 |
VBR Scale | 4 | 00 00 00 50 | 00000010 |
LAME header
第157~384字节:
Field | Length | 16进制 | Contents | 所在行号 |
---|---|---|---|---|
Encoder short VersionString | 9 | 4c 41 4d 45 33 2e 39 39 72 | LAME3.99r |
00000010 ~ 00000011 |
Info Tag revision + VBR method | 1 | 04 | 0x04 = 0000 0100b 修订号0, vbr mtrh |
00000011 |
Lowpass filter value | 1 | b9 | 18500Hz | 00000011 |
Peak signal amplitude | 4 | 00 00 00 00 | unknown | 00000011 |
Radio Replay Gain | 2 | 00 00 | 00000011 | |
Audiophile Replay Gain | 2 | 00 00 | 00000011 | |
Encoding flags + ATH Type | 1 | 35 | 0x35 = 0011 0101b | 00000011 |
if ABR {specified bitrate} else {minimal bitrate} | 1 | 20 | 00000012 | |
Encoder delays | 3 | 24 03 57 | 0x240357 = 100100000000 1101010111b 采样数是2304,最后一帧的0采样是855 |
00000012 |
Misc | 1 | 85 | 0x85 = 10 000 1 01b noise shaping 2,mono,yes,44.1kHz |
00000012 |
MP3 Gain | 1 | 00 | 不放大 | 00000012 |
Preset and surround info | 2 | 01 e0 | 0x01e0 = 00 00 000111100000b 无环绕声信息,480 |
00000012 |
MusicLength | 4 | 00 00 4b 90 | 0x00004b90 = 19344B = 18.890625KB | 00000012 |
MusicCRC | 2 | 9d 31 | 00000012 | |
CRC-16 of Info Tag | 2 | 9e 81 | 00000012 |
demo2
background.mp3,有ID3v2.3.0、ID3v1。
转换结果
|
|
分析
Field | Length | 16进制 | Contents | 所在行号 |
---|---|---|---|---|
ID3v2/file identifier | 3 | 49 44 33 | ID3 ,表示ID3v2 |
00000001 |
ID3v2 version | 2 | 03 00 | 表示3.0,和前面的连起来就是ID3v2.3.0 | 00000001 |
ID3v2 flags | 1 | 00 | 00000000 不使用 unsynchronisation 、后面没有extended header |
00000001 |
ID3v2 size | 4 | 00 00 1f 76 | 00000000 00000000 00011111 01110110,去掉字节首位后重新连接成28位,0000000 0000000 0011111 1110110 = 4086 = 255行余6,也就是到第256行数据结束为止 | 00000001 ~ 00000256 |
frame ID | 4 | 50 52 49 56 | PRIV = Private frame |
00000001 |
size | 4 | 00 00 00 0e | 0x0000000e = 14 | 00000001 ~ 00000002 |
flags | 2 | 00 00 | 00000002 | |
field | 14 | 50 65 61 6b 56 61 6c 75 65 00 21 7f 00 00 | PeakValue ! | 00000002 ~ 00000003 |
frame ID | 4 | 50 52 49 56 | PRIV = Private frame |
00000003 |
size | 4 | 00 00 00 11 | 0x00000011 = 17 | 00000003 |
flags | 2 | 00 00 | 00000003 | |
field | 17 | 41 76 65 72 61 67 65 4c 65 76 65 6c 00 7b 0d 00 00 | AverageLevel { | 00000003 ~ 00000004 |
frame ID | 4 | 54 50 45 31 | TPE1 = Lead performer(s)/Soloist(s) |
00000004 ~ 00000005 |
size | 4 | 00 00 00 0d | 0x0000000d = 13 | 00000005 |
flags | 2 | 00 00 | 00000005 | |
field | 13 | 00 47 6c 65 6e 6e 20 4b 61 73 74 65 6e | Glenn Kasten | 00000005 ~ 00000006 |
frame ID | 4 | 54 41 4c 42 | TALB = Album/Movie/Show title |
00000006 |
size | 4 | 00 00 00 08 | 0x00000008 = 8 | 00000006 |
flags | 2 | 00 00 | 00000006 | |
field | 8 | 00 55 6e 6b 6e 6f 77 6e | Unknown | 00000006 ~ 00000007 |
frame ID | 4 | 54 49 54 32 | TIT2 = Title/songname/content description |
00000007 |
size | 4 | 00 00 00 21 | 0x00000021 = 33 | 00000007 |
flags | 2 | 00 00 | 00000007 | |
field | 33 | 00 42 61 63 6b 67 72 6f 75 6e 64 20 66 6f 72 20 74 61 6c 6b 69 6e 67 20 62 75 74 20 64 6f 6e 27 74 | Background for talking but don’t | 00000008 ~ 00000010 |
frame ID | 4 | 54 59 45 52 | TYER = Year |
00000010 |
size | 4 | 00 00 00 05 | 0x00000005 = 5 | 00000010 |
flags | 2 | 00 00 | 00000010 | |
field | 5 | 00 32 30 30 38 | 2008 | 00000010 |
frame ID | 4 | 43 4f 4d 4d | COMM = Comments |
00000011 |
size | 4 | 00 00 00 2f | 0x0000002f = 47 | 00000011 |
flags | 2 | 00 00 | 00000011 | |
field | 47 | 00 58 58 58 00 43 6f 70 79 72 69 67 68 74 20 32 30 30 38 20 47 6c 65 6e 6e 20 4b 61 73 74 65 6e 2c 20 6c 69 63 65 6e 73 65 20 43 43 3a 42 59 | XXX Copyright 2008 Glenn Kasten, license CC:BY | 00000011 ~ 00000014 |
frame ID | 4 | 54 43 4f 4e | TCON = Content type |
00000014 |
size | 4 | 00 00 00 05 | 0x00000005 = 5 | 00000014 ~ 00000015 |
flags | 2 | 00 00 | 00000015 | |
field | 5 | 00 28 32 34 29 | (24) | 00000015 |
frame ID | 4 | 54 52 43 4b | TRCK = Track number/Position in set |
00000015 |
size | 4 | 00 00 00 02 | 0x00000002 = 2 | 00000015 |
flags | 2 | 00 00 | 00000016 | |
field | 2 | 00 39 | 9 | 00000016 |
padding | 全是00 | 第16行的第5个数据 ~ 第256行数据结束 | 00000016 ~ 00000256 | |
数据帧 | 第257行数据开始 ~ 第160627行的前2个数据 | 00000257 ~ 00160627 | ||
ID3v1 tag | 3 | 54 41 47 | TAG |
00160627 |
Title | 30 | 42 61 63 6b 67 72 6f 75 6e 64 20 66 6f 72 20 74 61 6c 6b 69 6e 67 20 62 75 74 20 64 6f 6e | Background for talking but don | 00160627 ~ 00160629 |
Artist | 30 | 47 6c 65 6e 6e 20 4b 61 73 74 65 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | Glenn Kasten | 00160629 ~ 00160631 |
Album | 30 | 55 6e 6b 6e 6f 77 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | Unknown | 00160631 ~ 00160632 |
Year | 4 | 32 30 30 38 | 2008 | 00160632 ~ 00160633 |
Comment | 30 | 43 6f 70 79 72 69 67 68 74 20 32 30 30 38 20 47 6c 65 6e 6e 20 4b 61 73 74 65 6e 2c 00 09 | Copyright 2008 Glenn Kasten, | 00160633 ~ 00160635 |
Genre | 1 | 18 | 00160635 |