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";
ID3V2
ID3V2 到现在一共有4个版本{ID3V2.1,ID3V2.2 ID3V2.3 ID3V2.4},最流行的为
第3版,即 ID3V2.3 ,由于ID3V1记录在文件末尾,ID3V2一般记录在文件头,据闻ID3V2.4也可以记录在文件末尾。
ID3V2特点:可伸缩可扩展,支持多编码,结构复杂,操作速度较慢。
ID3V2 存储格式: 标签头【10字节】&& 若干标签帧 ||扩展标签头【10字节】
现在看结构信息:
1,标签头
一般在文件首部记录10个字节的ID3V2头部【ID3V2.4也可能记录在其他地方】
标签头必须是 "ID3",否则认为标签不存在;
机构如下:
char Header[3]; /*必须为 "ID3" 否则认为标签不存在*/
char Ver; /*ID3V2版本号,ID3V2.3 就记录3*/
char Revision: /*副版本号,一般为0*/
char Flag; /*存放标志字节,一般全部为0*/
char Size[4]; /*所有标签大小,不包括标签头的10个字节*/
1》版本 Ver;
用二进制方式存储ID3V2版本号:
目前常见的有: 2,3,4对应 ID3V2.2 ID3V2.3 ID3V2.4,
ID3V2.1 没见到过,也未查到资料,请熟悉的朋友发份邮件给我(smtqiang#gmail.com);
2》Flag: 标志 定义如下:
abcd0000
a -- 表示是否使用 Unsynchronisation <一般为0-128,代表是否已经同步,这个标志主要为以前版本准备的,新的实现可以忽略这个标志,ID3V2.4一般为 128,ID3V2.3 多为 0>;
b -- 表示是否有扩展头部,格式为:
扩展头大小 4 个字节
扩展标志 2个字节
填充 4个字节
一般没有扩展标签头【b=0】
c -- 表示是否为测试标签,默认为0,不用设置
d -- 表示ID3V2最后是否含有Footer.
最后4位不使用
3》Size[4]: ID3V2所有标签大小,不包含 10字节的标签头;
一个4个字节,但每个字节只用7位,最高位不使用为0,格式如下:
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
计算大小时要将0去掉,得到一个28位的二进制数,就是标签大小,计算公式如下:
int total_size;
total_size = ((Size[0] & 0x7f)<<21)+((Size[1] & 0x7f)<<14)+((Size[2] & 0x7f)<<7)+(Size[3] & 0x7f)
2, 扩展头
扩展头包含了更多的数据信息,是对ID3V2的补充,但是并非解析MP3文件的关键数据,是否有扩展头,对应于ID3V2 Flag.
3, ID3V2 标签帧
每个ID3V2标签含有一个或多个ID3V2帧,每个帧有ID3V2帧头和帧体构成:例如;
FrameID[4]+FrameSize[4]+Flags[2]+FrameCont_encode+FrameCont;
ID3V2.4和ID3V2.3帧体结构:
FrameID[4] /*四个字节的帧ID,比如TIT2(mp3歌曲名),TPE1(歌手名)等*/
FrameSize[4] /*帧体大小,4个字节都可以使用,共计32位,注:不包含帧ID大小,包含帧体字符编码一个字节加帧体内容*/
Flags[2] /*帧体填充,2个字节,一般不设置,用\0填充*/
FrameCont_encode /*帧体字符所用编码*/
FrameCont /*帧体部分,字节长度为FrameSize[4] = FrameCont_encode.length+FrameCont.length*/
注:FrameSize[4],Flags[2],FrameCont_encode,都为二进制格式存储,为明确指明的为原字符存储;
FrameCont_encode 有4个值;
0000 0000 代表帧体用 ISO-8859-1 编码方式存储;
0000 0001 代表帧体用 UTF-16LE 编码方式存储;
0000 0002 代表帧体用 UTF-16BE 编码方式存储;
0000 0003 代表帧体用 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: 音轨号/综合音轨号
5, ID3V2.2
因ID3V2.2有些特殊,在此做下介绍:
ID3V2.2的帧标签与ID3V2.3 ID3V2.4 有些差异,结构如下:
char FrameID[3]; /*用三个字符标示一个帧ID,比如 TT2(歌曲名),TP1(艺术家)*/
char Size[3]; /*帧体内容大小,不包含帧ID,不到小于1*/
char FrameCont_encode /*帧体字符所用编码*/
char FrameCont /*帧体字符*/
注: 注意它没有填充:
常用帧标示:
TT2: 标题 TP1: 艺术家
TAL: 专辑名 TRK: 音轨号/合计音轨
TYE: 发行日期 COM: 注释
TEN: 编码方式 TCO: 流派
APEV
1, 帧头:
APEV标签位置不固定,可能在文件末尾也可能在文件头,比较常见的存放位置为 ID3V1之前;
位置查找:
1,文件尾查找, 如果文件有ID3V1,则 文件指针向前移动128+32=160个字节,如果文件没有ID3V1,则向前移动32字节
原因为APEV标签的标签头和标签尾都是32个字符:
2,文件头查找, 如果有ID3V2,则文件指针向后移动ID3V2帧内容大小,如果没有ID3V2,则在文件头查找;
APEV2 帧头结构:
char header[8] /*APEV关键字 "APETAGEX",如果没有则表示不存在 APEV2信息*/
char version[4] /*APEV版本,如现在常用的APEV2*/
char tagSize[4] /*APEV 标签大小,包含标签尾,但不包含标签头*/
char itemCount[4] /*标签元素个数*/
char tagflags[4] /*填充*/
char reserved[8] /*标签保留,值全部为\0*/
标签帧信息格式:
char itemValSize[4] /*标签内容大小*/
char itemflags[4] /*填充*/
char itemID /*标签内容标示,如Year(发行日期),Track 音轨号.大小不固定*/
char itemPre[1] /*标签ID与标签内容之间的间隔,值为\0*/
char itemValue /*标签内容,占itemValSize[4]字节*/
注:itemValue 一般用UTF-8编码存储:
常用帧标示:
Year 发行日期
Genre 流派
Track 音轨号
Album 专辑名
Title 歌曲名
Artist 歌手名
Encoder 编码类型
Composer 作曲家
Orchestra 乐队