ID3官网: http://www.id3.org/
一. MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)
ID3V2
包含了 作者,作曲,专辑 等信息,长度不固定,扩展了ID3V1的信息量。
Frame
一系列的帧,个数由文件大小和帧长决定
每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定
每个FRAME又分为 帧头 和 数据实体 两部分
帧头记录了mp3的 位率,采样率,版本 等信息,每个帧之间相互独立
ID3V1
包含了 作者,作曲,专辑 等信息,长度为128BYTE。
二. MP3帧头中除了存储一些象private、copyright、original的简单音乐说明信息以外,没有考虑存放歌名、作者、专辑名、年份等复杂信息,而这些信息在MP3应用中非常必要。1996年,FricKemp在“Studio 3”项目中提出了在MP3文件尾增加一块用于存放歌曲的说明信息,形成了ID3标准,至今已制定出ID3 V1.0,V1.1,V2.0,V2.3和V2.4标准。版本越高,记录的相关信息就越丰富详尽
三. ID3V2 到现在一共有 4 个版本,但流行的播放软件一般只支持第 3 版,既 ID3v2.3。由于 ID3V1 记录在 MP3 文件的末尾,ID3V2 就只好记录在 MP3 文件的首部了(如果有一天发布 ID3V3,真不知道该记录在哪里)。也正是由于这个原因,对 ID3V2 的操作比 ID3V1 要慢。而且 ID3V2 结构比 ID3V1 的结构要复杂得多,但比前者全面且可以伸缩和扩展。
下面就介绍一下 ID3V2.3。
每个 ID3V2.3 的标签都一个标签头和若干个标签帧或一个扩展标签头组成。关于曲目的信息如标题、作者等都存放在不同的标签帧中,扩展标签头和标签帧并不是必要的,但每个标签至少要有一个标签帧。标签头和标签帧一起顺序存放在 MP3 文件的首部。
1、标签头
在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号 ID3V2.3 就记录 3(就是3,不是ascii码)*/
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)*0x4000
+(Size[2]&0x7F)*0x80
+(Size[3]&0x7F)
2、标签帧
每个标签帧都有一个 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 表示备注所使用的自然语言
更详细的内容请参考 http://id3.org/id3v2.3.0 第4节Declared ID3v2 frames
2).大小
这个可没有标签头的算法那么麻烦,每个字节的 8 位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x1000000
+Size[1]*0x10000
+Size[2]*0x100
+Size[3];
3).标志
只定义了 6 位,另外的 10 位为 0,但大部分的情况下 16 位都为 0 就可以了。格式如下:
abc00000 ijk00000
a -- 标签保护标志,设置时认为此帧作废
b -- 文件保护标志,设置时认为此帧作废
c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)
i -- 压缩标志,设置时一个字节存放两个 BCD 码表示数字
j -- 加密标志(没有见过哪个 MP3 文件的标签用了加密)
k -- 组标志,设置时说明此帧和其他的某帧是一组
四. 图片帧在 帧id 为 APIC 的帧中 , 其中 帧数据是下面的 结构
<Header for 'Attached picture', ID: "APIC">
Text encoding $xx
MIME type <text string> $00
Picture type $xx
Description <text string according to encoding> $00 (00)
Picture data <binary data>
即 要从帧的数据部分 跳过1字节,再跳过一个以\0为结尾的字符串, 再跳过1字节,再跳过一个以\0为结尾的字符串,后面才是 图片数据