MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)
这里分析的MP3:BOBO-光荣
MP3下载链接(不确定从一个歌二进制数据是否一致):
ID3V2:(ID3V2.3)
1.标签头
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号ID3V2.3 就记录3*/
char Revision; /*副版本号此版本记录为0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/
Flag:标志字节
标志字节一般为0,定义如下:
abc00000
a -- 表示是否使用Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)
b -- 表示是否有扩展头部,一般没有(至少Winamp 没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
size[4]: 标签大小
一共四个字节,但每个字节只用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)
这里要注意它们的地址,等会实例会进行分析。
2, 扩展头
扩展头包含了更多的数据信息,是对ID3V2的补充,但是并非解析MP3文件的关键数据,是否有扩展头,对应于ID3V2 Flag 的b.
3.标签帧 (帧头和帧体)
帧头:
char FrameID[4]; /*用四个字符标识一个帧*/
char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/
帧体:
Flags[2] /*帧体填充,2个字节,一般不设置,用\0填充*/
FrameCont_encode /*帧体字符所用编码*/
FrameCont /*帧体部分,字节长度为FrameSize[4] = FrameCont_encode.length+FrameCont.length*/
FrameCont_encode 有4个值;
0000 0000 代表帧体用 ISO-8859-1 编码方式存储;
0000 0001 代表帧体用 UTF-16LE 编码方式存储;
0000 0010 代表帧体用 UTF-16BE 编码方式存储;
0000 0011 代表帧体用 UTF-8 编码方式存储;[只用ID3V2.4才支持UTF-8编码方式]
4.ID3V2 尾:
ID3V2 尾(Footer)是可选的,有时候可能需要从MP3文件的尾部向前搜索ID3V2的位置,这时候ID3V2的存在就可以
加快搜索的速度,ID3V2尾和ID3V2头的内容是一致的,只是文件头标示部分由 "ID3" 改成了 "3DI";
下面附上一些 FrameID帧标: 用4个字符标示一个帧的内容,常用对照如下:
TCOP: 版权 TOPE: 原艺术家
TDAT: 日期 TPE3: 指挥者
TPE1: 艺术家 TYER: 专辑发行年代
USLT: 歌词 TALB: 专辑名称
TIT2: 歌曲名称 TCON: 流派
COMM: 注释 TRCK: 音轨号/综合音轨号
对MP3文件分析:
标签头: char Header[3] 3 bytes: 49 44 33 "ID3"
char Ver 1 bytes: 03 版本ID3V2.3
char Revision 1 bytes: 00
char Flag 1 bytes: 00 没有扩展头
char Size[4] 4 bytes: 00 00 01 76
0 0 0 0 0 1 7 6
对SIze的大小确定; 0000 0000 0000 0000 0000 0001 0111 0110
去掉每个字节的最高位: 000 0000 000 0000 000 0001 111 0110
则最后的大小(高地址在低位 big endian): 11110110 ->0xf6 不包括自身的10字节 如果加上自身的10字节则为0x100
所以、整个ID3V2大小为0x100 区间在0x00 ~ 0xff 之后0x100就是帧数据(FRAME)
标签帧: 含有一个或多个标签帧。
1. frame[4]: 54 43 4f 4e TCON(类型)
size[4] : 00 00 00 05
flags[2] : 00 00
size大小为5,包括一个字节的帧体编码和4字节帧体数据
编码: 00
帧体: 28 31 32 39
2. frame[4]: 54 41 4c 42 TALB(专辑)
size[4] : 00 00 00 05
flag[2] : 00 00
编码: 00
帧体: B9 E2 C8 D9 (光荣)
3.frame[4]: 54 43 4F 50 TCOP(版权)
size[4] : 00 00 00 01
flag[2] : 00 00
编码 : 00
4.frame[4]: 54 49 54 32 TIT2(标题)
size[4] : 00 00 00 05
flag[2] : 00 00
编码 : 00
帧体 : B9 E2 CB D9 (光荣)
5.frame[4]: 54 50 45 31 TPE1(作者)
size[4] : 00 00 00 05
flag[2] : 00 00
编码: : 00
帧体 : 42 4F 42 4F (BOBO)
ID3V1:
ID3V1 mp3信息的简单存储格式,它存储在mp3文件末尾,大小为128个字节,标签头为3个字节,标签头必须为“TAG”,否则认为没有ID3V1标签;
数据格式:
char Header[3]; /*标签头必须为 "TAG" 否则认为没有标签*/
char Title[30]; /*歌曲名称*/
char Artist[30]; /*作者*/
char Album[30]; /*专辑名称*/
char Year[4]; /*出品年代*/
char Comment[28]; /*备注*/
char reserve; /*保留(二进制存储,默认为0)*/
char track; /*音轨号(二进制存储,歌曲在专辑中的编号)*/
char Genre; /*流派(二进制存储,乐风)*/
ID3V1 各项信息都是顺序存储,没有任何标识将其分开,各个信息字节说是
固定的,字节数不足的需用 ‘\0’补充;
ID3V1 存储编码只能用 ISO-8859-1;
Genre=流派
0="Blues"; 1="ClassicRock"; 2="Country"; 3="Dance";
4="Disco"; 5="Funk"; 6="Grunge"; 7="Hip-Hop";
8="jazz"; 9="Metal"; 10="NewAge"; 11="Oldies";
12="Other"; 13="Pop"; 14="R&B"; 15="Rap";
16="Reggae"; 17="Rock"; 18="Techno"; 19="Industrial";
20="Alternative"; 21="Ska"; 22="DeathMetal"; 23="Pranks";
24="Soundtrack"; 25="Euro-Techno"; 26="Ambient"; 27="Trip-Hop";
28="Vocel"; 29="Jazz+Funk"; 30="Fusion"; 31="Trance";
32="Classical"; 33="Instrumental"; 34="Acid"; 35="House";
36="Game"; 37="SoundClip"; 38="Gospel"; 39="Noise";
40="AlternRock"; 41="Bass"; 42="Soul"; 43="Punk";
44="Space"; 45="Meditative"; 46="InstrumentalPop"; 47="InstrumentalRock";
48="Ethnic"; 49="Gothic"; 50="Darkwave"; 51="Techno-Industrial";
52="Electronic"; 53="Pop-Folk"; 54="Eurodance"; 55="Dream";
56="SouthernRock"; 57="Comedy"; 58="Cult"; 59="Gangsta";
60="Top40"; 61="ChristianRap"; 62="Pop/Funk"; 63="Jungle";
64="NativeAmerican"; 65="Cabaret"; 66="NewWave"; 67="Psychadelic";
68="Rave"; 69="Showtunes"; 70="Trailer"; 71="Lo-Fi";
72="Tribal"; 73="AcidPunk"; 74="AcidJazz"; 75="Polka";
76="Retro"; 77="Musical"; 78="Rock&Roll"; 79="HardRock";
/* Extended genres */
80="Folk"; 81="Folk-Rock"; 82="NationalFolk"; 83="Swing";
84="FastFusion"; 85="Bebob"; 86="Latin"; 87="Revival";
88="Celtic"; 89="Bluegrass"; 90="Avantgarde"; 91="GothicRock";
92="ProgessiveRock"; 93="PsychedelicRock"; 94="SymphonicRock"; 95="SlowRock";
96="BigBand"; 97="Chorus"; 98="EasyListening"; 99="Acoustic";
100="Humour"; 101="Speech"; 102="Chanson"; 103="Opera";
104="ChamberMusic";105="Sonata"; 106="Symphony"; 107="BootyBass";
108="Primus"; 109="PornGroove"; 110="Satire"; 111="SlowJam";
112="Club"; 113="Tango"; 114="Samba"; 115="Folklore";
116="Ballad"; 117="PowerBallad"; 118="RhythmicSoul"; 119="Freestyle";
120="Duet"; 121="PunkRock"; 122="DrumSolo"; 123="Acapella";
124="Euro-House"; 125="DanceHall"; 126="Goa"; 127="Drum&Bass";
128="Club-House"; 129="Hardcore"; 130="Terror"; 131="Indie";
132="BritPop"; 133="Negerpunk"; 134="PolskPunk"; 135="Beat";
136="ChristianGangstaRap"; 137="HeavyMetal"; 138="BlackMetal"; 139="Crossover";
140="ContemporaryChristian"; 141="ChristianRock"; 142="Merengue"; 143="Salsa";
144="TrashMetal"; 145="Anime"; 146="JPop"; 147="Synthpop";
找到MP3文件的最后128个字节.
char Header[3] 3: 54 41 47 TAG
char Title[30] 30: B9 E2 C8 D9 歌名 "光荣“
char Artist[30] 30: 42 4F 42 4F 歌手 "BOBO"
char Album[30] 30: 39 E2 C8 D9 专辑 "光荣"
。。。。
。。。。
。。。。
char Genre 1: 0c "Other"
最后就是FRAME数据的分析。。。。
敬请期待。。。
本文为自己分析所得,难免存在错误。。。请多多指点!。