ID3V1和ID3V2的分析

来源:互联网 发布:手机淘宝在哪里秒杀 编辑:程序博客网 时间:2024/06/06 07:16

ID3V1和ID3V2的分析

ID3v1
    ID3V1比较简单,它是存放在MP3文件的末尾,用16进制的编辑器打开一个MP3文件,查看其末尾的128个顺序存放字节,数据结构定义如下:
char Header[3];     /*标签头必须是"TAG"否则认为没有标签*/
char Title[30];     /*标题*/
char Artist[30];    /*作者*/
char Album[30];     /*专集*/
char Year[4];     /*出品年代*/
char Comment[30];    /*备注*/
char Genre;     /*类型,流派*/
    ID3V1的各项信息都是顺序存放,没有任何标识将其分开,比如标题信息不足30个字节,则使用'\0'补足,否则将造成信息错误。Genre使用原码表示,对照表如下(略):

ID3V2
    ID3V2到现在一共有4个版本,但流行的播放软件一般只支持第3版,既ID3v2.3。由于ID3V1记录在MP3文件的末尾,ID3V2就只好记录在MP3文件的首部了。也正是由于这个原因,对ID3V2的操作比ID3V1要慢。而且ID3V2结构比ID3V1的结构要复杂得多,但比前者全面且可以伸缩和扩展。

每个ID3V2.3的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在MP3文件的首部。

一、 标签头   

在文件的首部顺序记录10个字节的ID3V2.3的头部。数据结构如下:
char Header[3];     /*必须为"ID3"否则认为标签不存在*/
char Ver;     /*版本号ID3V2.3就记录3*/
char Revision;     /*副版本号此版本记录为0*/
char Flag;     /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4];     /*标签大小,包括标签头的10个字节和所有的标签帧的大小*/

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)*0x400 + (Size[2]&0x7F)*0x80
              +(Size[3]&0x7F)
二、标签帧
每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。

帧头的定义如下:
char FrameID[4];   /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/
char Size[4];    /*帧内容的大小,不包括帧头,不得小于1*/ 
char Flags[2];    /*存放标志,只定义了6位,稍后详细解说*/
1.帧标识
用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:
TIT2=标题 表示内容为这首歌的标题,下同

APIC=attached picture(专辑封面)
TPE1=作者

TOPE=艺术家
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',并把这个字节计算在帧内容的大小中。

3.帧数据(内容)

       这里首先介绍一下帧数据为字符串时的存储格式。所有的字符串(URL也算)都采用ISO-8859-1或Unicode的方式进行编码,前者字符串以0x00结尾,后者以0x00 0x00结尾。通常情况下字符串不能包含换行符。一般来讲,如果帧数据保存的是字符串,那第一个字节表示编码方式,如果是ISO-8859-1就为0x00,如果是Unicode则为0x01.

       实际上大部分常用标签都是数据是字符串形式

       TENC WXXX COMM TRCK(不能肯定)TYER(不能肯定) TEP2 TCOM TOPE TCON TALB APIC

       而只有PRIV不是

      

       帧标识为APIC时表示该帧的数据为一幅图片,图片格式为MIME类型。如果MIME类型被省略,默认会使用”image/png” or “image/jpeg”。同一个音频文件可包含多幅图片,每个都有自己的APIC帧,但只有一个有效。此外,还可以通过设置MIMI类型为“-à”来指定一个图片的链接。下面是一个完整的APIC帧的例子:

帧头:APIC|00 00 49 D9|00 00 | . image/jpg…|完整的jpg文件数据

APIC为帧标识符,为方便看已经转化为char了

00 00 49 D9 表示该帧所包含的数据长度,18905个字节,但注意,这18905个字节是整个数据区的长度,不包括帧头。

00 00 表示flag,用不上。

. image/jpg… 数据区的前13bytes,第一个字节(.)的含义前面已经说了。后面12bytes的长度是固定的,但其中的“jpg”图片类型的变化而变化,但总是三位,如果载入的文件类型为“*.jpeg”那这三位就是“peg”,其它类推。紧跟着的才是真正的图片数据区了,所以图片数据长度只有18905-13bytes,这里存放的数据和jpg原图的数据一模一样(通过ultra edit比较的结果),把这部分的数据提出来保存为jpg文件和原图没有任何区别。


原创粉丝点击