Mp3文件由帧组成,帧分成标签帧和数据帧,本文就Mp3文件的帧进行分析。
一、标签帧
MP3帧头中除了存储一些象private、copyright、original的简单音乐说明信息以外,没有考虑存放歌名、作者、专辑名、年份 等复杂信息,而这些信息在MP3应用中非常必要。1996年,FricKemp在“Studio 3”项目中提出了在MP3文件尾增加一块用于存放歌曲的说明信息,形成了ID3标准,至今已制定出ID3 V1.0,V1.1,V2.0,V2.3和V2.4标准。版本越高,记录的相关信息就越丰富详尽。
1.ID3V2标签帧
每个 ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个 标签至少要有一个标签帧。标签头和标签帧一起顺序存放在 MP3 文件的首部,标签紧随标签头存放。接下来将以一个实际例子贯穿整篇文章,红色字体部分为解析例子的内容。如下图,一个ID3V2的帧,蓝精灵的主题曲,哈 哈。
1.1标签头
在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在,如上图地址00—02部分为"49 44 33",文本为“ID3”*/
char Ver; /*版本号 ID3V2.3 就记录 3,如上图地址03处记录为"03"*,/
char Revision; /*副版本号此版本记录为 0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说,这里为00*/
char Size[4]; /*标签大小,包括标签头的 10 个字节和所有的标签帧的大小,这里为623+10=633个字节,计算方法见下文*/
1).标志字节
标志字节一般为 0,定义如下:
abc00000
a -- 表示是否使用 Unsynchronisation
b -- 表示是否有扩展头部,一般没有(至少 Winamp 没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
2).标签大小
一共四个字节,读取顺序为big-endia(低地址向高地址读取)但每个字节只用 7 位,最高位不使用恒为 0。所以格式如下
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
计算大小时要将 0 去掉,得到一个 28 位的二进制数,就是标签大小(不懂为什么要这样做,应该是MP3规范定义好的),计算公式如
下:
Size = (Size[0]&0x7F)*0x200000 +(Size[1]&0x7F)*0x400 +(Size[2]&0x7F)*0x80 +(Size[3]&0x7F)
= (Size[0]&0x7F)*2*16^5 +(Size[1]&0x7F)*4*16^2 +(Size[2]&0x7F)*8*16 +(Size[3]&0x7F)
而整个帧的大小需要加上帧头的10个字节,即total_Size=Size+10
上述例子的标签大小字段为“00 00 04 6F”,所以Size=4*8*16+111=623(bytes),整个帧的大小为(623+10)=633字节,所以在0X279这个地址处将开始新的帧。举的这个例子中,0X279开始了新的数据帧。
2、标签帧
每个标签帧都有一个 10 个字节的帧头和至少一个字节的不固定长度的内容组成。 它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中得到内容大小后才能读出,读取时要注意大 小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char FrameID[4]; /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表,参见附录4*/
char Size[4]; /*帧内容的大小,不包括帧头,不得小于1,计算见下文*/
char Flags[2]; /*存放标志,只定义了 6 位,稍后详细解说*/
1).帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下,具体可以参照后文附录4(帧标识的含义):
TIT2=标题 表示内容为这首歌的标题,下同
TPE1=作者
TALB=专集
TRCK=音轨 格式:N/M 其中 N 为专集中的第 N 首,M 为专集* M 首,N 和 M 为 ASCII 码表示的数字
TYER=年代 是用 ASCII 码表示的数字
TCON=类型 直接用字符串表示
COMM=备注 格式:"eng\0 备注内容",其中 eng 表示备注所使用的自然语言
2).大小
这个可没有标签头的算法那么麻烦,每个字节的 8 位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
Size = Size[0]*0x100000000 +Size[1]*0x10000 +Size[2]*0x100 +Size[3]
= Size[0]*16^8 +Size[1]*16^4 +Size[2]*16^2 +Size[3]
而整个帧的大小需要加上帧头的10个字节,即total_Size=Size+10。
3).标志
只定义了 6 位,另外的 10 位为 0,但大部分的情况下 16 位都为 0 就可以了。格式如下:
abc00000 ijk00000
a -- 标签保护标志,设置时认为此帧作废
b -- 文件保护标志,设置时认为此帧作废
c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)
i -- 压缩标志,设置时一个字节存放两个 BCD 码表示数字
j -- 加密标志(没有见过哪个 MP3 文件的标签用了加密)
k -- 组标志,设置时说明此帧和其他的某帧是一组
值得一提的是 winamp 在保存和读取帧内容的时候会在内容前面加个'\0',并把这个字节计算在帧内容的
大小中。
结合例子分析:地址0xa至0xd为帧标识,帧标识为“WXXX”;地址0xe至 0x11为帧大小,即“00 00 00 02”,结合前面的公式size=2;地址0x12至0x13为flags字段,为“00 00”,地址0x14至0x15字段为本帧的内容,编码为“00 00 ”;所以标识为“WXXX”帧共占了12字节。以此类推,地址0x16至0x24存储的是标识为“COMM”帧,帧总大小为15字节,其中用了5个字节存 储COMM值,内容为“eng.”。
4).附:帧标识的含义
Declared ID3v2 frames
The following frames are declared in this draft.
AENC Audio encryption
APIC Attached picture
COMM Comments
COMR Commercial frame
ENCR Encryption method registration
EQUA Equalization
ETCO Event timing codes
GEOB General encapsulated object
GRID Group identification registration
IPLS Involved people list
LINK Linked information
MCDI Music CD identifier
MLLT MPEG location lookup table
OWNE Ownership frame
PRIV Private frame
PCNT Play counter
POPM Popularimeter
POSS Position synchronisation frame
RBUF Recommended buffer size
RVAD Relative volume adjustment
RVRB Reverb
SYLT Synchronized lyric/text
SYTC Synchronized tempo codes
TALB Album/Movie/Show title
TBPM BPM (beats per minute)
TCOM Composer
TCON Content type
TCOP Copyright message
TDAT Date
TDLY Playlist delay
TENC Encoded by
TEXT Lyricist/Text writer
TFLT File type
TIME Time
TIT1 Content group description
TIT2 Title/songname/content description
TIT3 Subtitle/Description refinement
TKEY Initial key
TLAN Language(s)
TLEN Length
TMED Media type
TOAL Original album/movie/show title
TOFN Original filename
TOLY Original lyricist(s)/text writer(s)
TOPE Original artist(s)/performer(s)
TORY Original release year
TOWN File owner/licensee
TPE1 Lead performer(s)/Soloist(s)
TPE2 Band/orchestra/accompaniment
TPE3 Conductor/performer refinement
TPE4 Interpreted, remixed, or otherwise modified by
TPOS Part of a set
TPUB Publisher
TRCK Track number/Position in set
TRDA Recording dates
TRSN Internet radio station name
TRSO Internet radio station owner
TSIZ Size
TSRC ISRC (international standard recording code)
TSSE Software/Hardware and settings used for encoding
TYER Year
TXXX User defined text information frame
UFID Unique file identifier
USER Terms of use
USLT Unsychronized lyric/text transcription
WCOM Commercial information
WCOP Copyright/Legal information
WOAF Official audio file webpage
WOAR Official artist/performer webpage
WOAS Official audio source webpage
WORS Official internet radio station homepage
WPAY Payment
WPUB Publishers official webpage
WXXX User defined URL link frame
2.ID3V1标签帧
ID3 V1.0标准并不周全,存放的信息少,无法存放歌词,无法录入专辑封面、图片等。V2.0是一个相当完备的标准,但给编写软件带来困难,虽然赞成此格式的 人很多,在软件中真正实现的却极少。绝大多数MP3仍使用ID3 V1.0标准。此标准是将MP3文件尾的最后128个字节用来存放ID3信息,这128个字节使用说明见表3。
表3 ID3 V1.0文件尾说明
字节 |
长度 (字节) |
说 明 |
1-3 |
3 |
存放“TAG”字符,表示ID3 V1.0标准,紧接其后的是歌曲信息。 |
4-33 |
30 |
歌名 |
34-63 |
30 |
作者 |
64-93 |
30 |
专辑名 |
94-97 |
4 |
年份 |
98-127 |
30 |
附注 |
128 |
1 |
MP3音乐类别,共147种。 |
表4 MP3音乐类别:
0 |
'Blues' |
20 |
'Alternative' |
40 |
'AlternRock' |
60 |
'Top 40' |
1 |
'Classic Rock' |
21 |
'Ska' |
41 |
'Bass' |
61 |
'Christian Rap' |
2 |
'Country' |
22 |
'Death Metal' |
42 |
'Soul' |
62 |
'Pop/Funk' |
3 |
'Dance' |
23 |
'Pranks' |
43 |
'Punk' |
63 |
'Jungle' |
4 |
'Disco' |
24 |
'Soundtrack' |
44 |
'Space' |
64 |
'Native American' |
5 |
'Funk' |
25 |
'Euro-Techno' |
45 |
'Meditative' |
65 |
'Cabaret' |
6 |
'Grunge' |
26 |
'Ambient' |
46 |
'Instrumental Pop' |
66 |
'New Wave' |
7 |
'Hip-Hop' |
27 |
'Trip-Hop' |
47 |
'Instrumental Rock' |
67 |
'Psychadelic' |
8 |
'Jazz' |
28 |
'Vocal' |
48 |
'Ethnic' |
68 |
'Rave' |
9 |
'Metal' |
29 |
'Jazz+Funk' |
49 |
'Gothic' |
69 |
'Showtunes' |
10 |
'New Age' |
30 |
'Fusion' |
50 |
'Darkwave' |
70 |
'Trailer' |
11 |
'Oldies' |
31 |
'Trance' |
51 |
'Techno-Industrial' |
71 |
'Lo-Fi' |
12 |
'Other' |
32 |
'Classical' |
52 |
'Electronic' |
72 |
'Tribal' |
13 |
'Pop' |
33 |
'Instrumental' |
53 |
'Pop-Folk' |
73 |
'Acid Punk' |
14 |
'R&B' |
34 |
'Acid' |
54 |
'Eurodance' |
74 |
'Acid Jazz' |
15 |
'Rap' |
35 |
'House' |
55 |
'Dream' |
75 |
'Polka' |
16 |
'Reggae' |
36 |
'Game' |
56 |
'Southern Rock' |
76 |
'Retro' |
17 |
'Rock' |
37 |
'Sound Clip' |
57 |
'Comedy' |
77 |
'Musical' |
18 |
'Techno' |
38 |
'Gospel' |
58 |
'Cult' |
78 |
'Rock & Roll' |
19 |
'Industrial' |
39 |
'Noise' |
59 |
'Gangsta' |
79 |
'Hard Rock' |
80 |
Folk |
81 |
Folk/Rock |
82 |
National Folk |
83 |
Swing |
84 |
Fast-Fusion |
85 |
Bebob |
86 |
Latin |
87 |
Revival |
88 |
Celtic |
89 |
Bluegrass |
90 |
Advantgarde |
91 |
Gothic Rock |
92 |
Progressive Rock |
93 |
Psychadelic Rock |
94 |
Symphonic Rock |
95 |
Slow Rock |
96 |
Big Band |
97 |
Chorus |
98 |
Easy Listening |
99 |
Acoustic |
100 |
Humour |
101 |
Speech |
102 |
Chanson |
103 |
Opera |
104 |
Chamber Music |
105 |
Sonata |
106 |
Symphony |
107 |
Booty Bass |
108 |
Primus |
109 |
Porn Groove |
110 |
Satire |
111 |
Slow Jam |
112 |
Club |
113 |
Tango |
114 |
Samba |
115 |
Folklore |
Any other value should be considered as 'Unknown' |
2.2 举例说明
还是蓝精灵的主题曲。
1)最开始的三个字节必须是“TAG”;第4至33个字节为歌名:蓝精灵;第34至63字节是作者:儿歌(竟然作者是儿歌,真没想到);第64字节 至93字节是专辑名:小红帽 儿歌经典\世纪之声-B碟(有乱码,这里是通过右键原Mp3文件查看的);年份没有记载内容,都是空格;附注有内容“00 0E”不知道是啥;音乐类别:Other(查表的结果)。