MP3文件结构及编解码流程
http://blog.sina.com.cn/s/blog_67b7cb7b01018i2l.html
http://blog.csdn.net/liuyan4794/article/details/7746993
MPEG音频标签分为两种,一种是ID3v1,存在文件尾部,长度128字节,另一种是ID3v2,是对ID3v1的扩展,存在文件头部,长度不定。
1、ID3v1
ID3v1标签用来描述MPEG音频文件。包含艺术家,标题,唱片集,发布年代和流派。另外还有额外的注释空间。位于音频文件的最后固定为128字节。可以读取该文件的最后这128字节获得标签。
结构如下
AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB
BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE
EFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFG
符号 |
长度 (bytes) |
位置 (bytes) |
描述 |
A |
3 |
(0-2) |
标签标志。如果存在标签并且正确的话,必须包含'TAG'。 |
B |
30 |
(3-32) |
标题 |
C |
30 |
(33-62) |
艺术家 |
D |
30 |
(63-92) |
唱片集 |
E |
4 |
(93-96) |
年代 |
F |
30 |
(97-126) |
注释 |
G |
1 |
(127) |
流派 |
该规格要求所有的空间必须以空字符(ASCII 0)填充。但是并不是所有的应用程序遵循该规则,比如winamp就用空格(ASCII 32)代替之。
在ID3v1.1结构中有些改变。注释部分的最后一个字节用来定义唱片集中的轨道号。如果不知道该信息时可以用空字符(ASCII 0)代替。
流派使用原码表示,为下列数字之一:
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' |
Winamp扩充了这个表
80 |
'Folk' |
92 |
'Progressive Rock' |
104 |
'Chamber Music' |
116 |
'Ballad' |
81 |
'Folk-Rock' |
93 |
'Psychedelic Rock' |
105 |
'Sonata' |
117 |
'Poweer Ballad' |
82 |
'National Folk' |
94 |
'Symphonic Rock' |
106 |
'Symphony' |
118 |
'Rhytmic Soul' |
83 |
'Swing' |
95 |
'Slow Rock' |
107 |
'Booty Brass' |
119 |
'Freestyle' |
84 |
'Fast Fusion' |
96 |
'Big Band' |
108 |
'Primus' |
120 |
'Duet' |
85 |
'Bebob' |
97 |
'Chorus' |
109 |
'Porn Groove' |
121 |
'Punk Rock' |
86 |
'Latin' |
98 |
'Easy Listening' |
110 |
'Satire' |
122 |
'Drum Solo' |
87 |
'Revival' |
99 |
'Acoustic' |
111 |
'Slow Jam' |
123 |
'A Capela' |
88 |
'Celtic' |
100 |
'Humour' |
112 |
'Club' |
124 |
'Euro-House' |
89 |
'Bluegrass' |
101 |
'Speech' |
113 |
'Tango' |
125 |
'Dance Hall' |
90 |
'Avantgarde' |
102 |
'Chanson' |
114 |
'Samba' |
||
91 |
'Gothic Rock' |
103 |
'Opera' |
115 |
'Folklore' |
其他扩充
126 |
'Goa' |
132 |
'BritPop' |
138 |
'BlackMetal' |
144 |
'TrashMetal' |
127 |
'Drum&Bass' |
133 |
'Negerpunk' |
139 |
'Crossover' |
145 |
'Anime' |
128 |
'Club-House' |
134 |
'PolskPunk' |
140 |
'ContemporaryChristian' |
146 |
'JPop' |
129 |
'Hardcore' |
135 |
'Beat' |
141 |
'ChristianRock' |
147 |
'Synthpop' |
130 |
'Terror' |
136 |
'ChristianGangstaRap' |
142 |
'Merengue' |
||
131 |
'Indie' |
137 |
'HeavyMetal' |
143 |
'Salsa' |
其他任何的数值都认为是“unknown”
2、ID3V2
ID3V2 到现在一共有4 个版本,但流行的播放软件一般只支持第3 版,既ID3v2.3。由于ID3V1 记录在MP3 文件的末尾,ID3V2
就只好记录在MP3 文件的首部了(如果有一天发布ID3V3,真不知道该记录在哪里)。也正是由于这个原因,对ID3V2 的操作比ID3V1
要慢。而且ID3V2 结构比ID3V1 的结构要复杂得多,但比前者全面且可以伸缩和扩展。
下面就介绍一下ID3V2.3。
每个ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3 文件的首部。
(一)、标签头
在文件的首部顺序记录10 个字节的ID3V2.3 的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号ID3V2.3 就记录3*/
char Revision; /*副版本号此版本记录为0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/
注:对这里我有疑惑,因为在实际寻找首帧的过程中,我发现有的mp3文件的标签大小是不包含标签头的,但有的又是包含的,可能是某些mp3编码器写标签的BUG,所以为了兼容只好认为其是包含的,如果按大小找不到,再向后搜索,直到找到首帧为止。
(1).标志字节
标志字节一般为0,定义如下:
abc00000
a -- 表示是否使用Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)
b -- 表示是否有扩展头部,一般没有(至少Winamp 没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
(2).标签大小
一共四个字节,但每个字节只用7 位,最高位不使用恒为0。所以格式如下
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
计算大小时要将0 去掉,得到一个28 位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如
下:
int total_size;
total_size = (Size[0]&0x7F)*0x200000
+(Size[1]&0x7F)*0x4000
+(Size[2]&0x7F)*0x80
+(Size[3]&0x7F)
len = (hdr[0] << 21) | (hdr[1] << 14) | (hdr[2] << 7) | hdr[3];
(二)、标签帧
每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件
中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大
小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char FrameID[4]; /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/
char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/
char Flags[2]; /*存放标志,只定义了6 位,稍后详细解说*/
(1).帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:
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
算法如下:
int FSize;
FSize = Size[0]*0x100000000
+Size[1]*0x10000
+Size[2]*0x100
+Size[3];
(3).标志
只定义了6 位,另外的10 位为0,但大部分的情况下16 位都为0 就可以了。格式如下:
abc00000 ijk00000
a -- 标签保护标志,设置时认为此帧作废
b -- 文件保护标志,设置时认为此帧作废
c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)
i -- 压缩标志,设置时一个字节存放两个BCD 码表示数字
j -- 加密标志(没有见过哪个MP3 文件的标签用了加密)
k -- 组标志,设置时说明此帧和其他的某帧是一组
值得一提的是winamp 在保存和读取帧内容的时候会在内容前面加个'/0',并把这个字节计算在帧内容的
大小中。
附:帧标识的含义
(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
注:读取参考实例
--------------------->ID3v2<---------------------
TPE1 ��?��`
TALB ��j�b�SAmjm
TIT2 ��j�b�SAmjm
TYER ��2013-04-10
APIC image/jpeg
TXXX ��Tagging time��2013-04-11T03:34:56
--------------------->ID3v2<---------------------
[root@gx6602 music]# busybox hexdump -n 256 -C withme.mp3
00000000 49 44 33 03 00 00 00 02 15 60 54 50 45 31 00 00 |ID3......`TPE1..|
00000010 00 07 00 00 01 ff fe 3f 96 84 60 54 41 4c 42 00 |.......?..`TALB.|
00000020 00 00 0d 00 00 01 ff fe 6a 96 11 62 bb 53 41 6d |........j..b.SAm|
00000030 6a 6d 54 49 54 32 00 00 00 0d 00 00 01 ff fe 6a |jmTIT2.........j|
00000040 96 11 62 bb 53 41 6d 6a 6d 54 59 45 52 00 00 00 |..b.SAmjmTYER...|
00000050 17 00 00 01 ff fe 32 00 30 00 31 00 33 00 2d 00 |......2.0.1.3.-.|
00000060 30 00 34 00 2d 00 31 00 30 00 41 50 49 43 00 00 |0.4.-.1.0.APIC..|
00000070 86 27 00 00 01 69 6d 61 67 65 2f 6a 70 65 67 00 |.'...image/jpeg.|
00000080 03 ff fe 65 00 00 00 ff d8 ff e0 00 10 4a 46 49 |...e.........JFI|
00000090 46 00 01 01 00 00 01 00 01 00 00 ff fe 00 3c 43 |F.............<C|
000000a0 52 45 41 54 4f 52 3a 20 67 64 2d 6a 70 65 67 20 |REATOR: gd-jpeg |
000000b0 76 31 2e 30 20 28 75 73 69 6e 67 20 49 4a 47 20 |v1.0 (using IJG |
000000c0 4a 50 45 47 20 76 36 32 29 2c 20 71 75 61 6c 69 |JPEG v62), quali|
000000d0 74 79 20 3d 20 31 30 30 0a ff db 00 43 00 01 01 |ty = 100....C...|
000000e0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................|