一 MP3文件整体结构
MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1)
ID3V2标签帧 | ID3v2在文件头,以字符串“ID3”为标志,包含了演唱者,作曲,专辑等信息,长度不固定,扩展了ID3V1的信息量。 |
音频数据帧 | 一系列的帧,个数由文件大小和帧长决定,每个FRAME的长度可能不固定,也可能固定,由位率bitrate决定,每个FRAME又分为帧头和数据实体两部分,帧头记录了mp3的位率,采样率,版本等信息,每个帧之间相互独立 |
ID3V1标签帧 | ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。 |
1. ID3V2标签帧
Ø 标签头:文件的首部顺序记录10 个字节的ID3V2.3 的头部。数据结构如下:
char Header[3]; /*必须为"ID3"否则认为标签不存在*/
char Ver; /*版本号ID3V2.3 就记录3*/
char Revision; /*副版本号此版本记录为0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/
49 44 33 03 00 00 00 02 7A 13
I D 3 版本号 副版本号
标签大小:00 02 7A13
int ID3V2_Size;
ID3V2_Size = (Size[0]&0x7F)*0x200000
+(Size[1]&0x7F)*0x4000
+(Size[2]&0x7F)*0x80
+(Size[3]&0x7F)
Ø 标签帧
每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。
帧头: charFrameID[4]; //帧标识
char Size[4]; //帧大小
char Flags[2]; //标志
54 50 45 31 00 00 00 0B 00 00 01 FF FE 77 7B 50 5B 44 51 1F 5F
T P E 1帧标识 size: 0x0000000B = 11 标志 11byte 内容
帧标识:
TIT2 = 标题
TPE1 = 作者
TRCK = 音轨
TYPE = 年代
COMM = 备注
2. 音频数据帧
每个帧都有4 字节帧头 + 2 字节CRC校验(存在是否由帧头决定)+ 尸体数据(MAIN_DATA)
Ø 帧头
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
FF FB E2 64
1111 1111 111 11011 1110 0010 0110 0100
符号 | 长度(bit) | 位置(bit) | 描述 |
A | 11 | (31~21) | 帧同步(所有位置1) |
B | 2 | (20~19) | MPEG 音频版本ID 00 – MPEG 2.5 01 –保留 10 – MPEG 2 (ISO/IEC 13818-3) 11 – MPEG 1 (ISO/IEC 11172-3) |
C | 2 | (18~17) | Layer描述 00 - 保留 01 - Layer III 10 - Layer II 11 - Layer I |
D | 1 | (16) | 校验位(0 - 紧跟帧头后有16位即2个字节用作CRC校验1 - 没有校验) |
E | 4 | (15~12) | 比特率(位率)(见比特率索引表) |
F | 2 | (11~10) | 采样率(见采样率索引表) |
G | 1 | (9) | 填充位(填充用来达到正确的比特率。) 0 –没有填充 1 –填充了一个额外的空位 |
H | 1 | (8) | 私有bit,可以用来做特殊应用。例如可以用来触发应用程序的特殊事件。 |
I | 2 | (7~6) | 声道 00 立体声 01 联合立体声(立体声) 10 双声道(立体声) 11 单声道(单声) |
J | 2 | (5~4) | 扩展模式(仅在联合立体声时有效) 扩展模式用来连接对立体声效果无用的信息,来减少所需的资源。这两个位在联合立体声模式下有编码器动态指定。 |
K | 1 | (3) | 版权 0无版权 1有版权 |
L | 1 | (2) | 原创 0 原创拷贝 1 原创 |
M | 2 | (1) | 强调 00 - 无 01 - 50/15 ms 10 - 保留 11 - CCIT J.17 |
【帧头信息表】
索引值 | MPEG1 | MPEG2&MPEG2.5 | |||
Layer1 | Layer2 | Layer3 | Layer1 | Layer2&3 | |
0000 | Free | ||||
0001 | 32 | 32 | 32 | 32 | 8 |
0010 | 64 | 48 | 40 | 48 | 16 |
0011 | 96 | 56 | 48 | 56 | 24 |
0100 | 128 | 64 | 56 | 64 | 32 |
0101 | 160 | 80 | 64 | 80 | 40 |
0110 | 192 | 96 | 80 | 96 | 48 |
0111 | 224 | 112 | 96 | 112 | 56 |
1000 | 256 | 128 | 112 | 128 | 64 |
1001 | 288 | 160 | 128 | 144 | 80 |
1010 | 320 | 192 | 160 | 160 | 96 |
1011 | 352 | 224 | 192 | 176 | 112 |
1100 | 384 | 256 | 224 | 192 | 128 |
1101 | 416 | 320 | 256 | 224 | 144 |
1110 | 448 | 384 | 320 | 256 | 160 |
1111 | Bad |
【比特率索引表】
Bits | MPEG1 | MPEG2 | MPEG3 |
00 | 44100 | 22050 | 11025 |
01 | 48000 | 24000 | 12000 |
10 | 32000 | 16000 | 8000 |
11 | 保留 |
【采样率索引表】
| MPEG1 | MPEG2 | MPEG2.5 |
Layer1 | 384 | 384 | 384 |
Layer2 | 1152 | 1152 | 1152 |
Layer3 | 1152 | 576 | 576 |
【每帧采样数表】
1) 如何计算音频数据帧长度
注意:因为有填充和比特率变换,帧长度可能变化。
从头中读取比特率,采样频率和填充,
LyaerI使用公式:
帧长度(字节) = 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 +填充 * 4
LyerII和LyaerIII使用公式:
帧长度(字节)= 每帧采样数 / 采样频率(HZ) * 比特率(bps)/ 8 + 填充
例:
LayerIII 比特率128000,采样频率 44100,填充0
=〉帧大小 417字节
播放时长= (文件大小– ID3大小)*8 / bitrate(bit/s)
Duration = 总帧数*每帧采样数/采样率 sampleRate
2) 计算每帧的持续时间
每帧持续时间(秒)= 每帧采样数 /采样频率(HZ)
3. ID3V1标签帧
ID3v1在文件结尾,以字符串“TAG”为标记,其长度是固定的128个字节,包含了演唱者、歌名、专辑、年份等信息。
结构:
AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB
BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD
DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE
EFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFG
符号 | 长度(byte) | 位置 | 描述 |
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) | 流派 |
二、解析方法
当你想读取MPEG文件的信息时,解析前三个字节,判断是否有ID3V2标签,有则根据上面的方法算出ID3V2标签的总大小,这样就找到了音频数据帧的第一帧,读取它的头信息,获取比特率、采样率、MPEG版本号、Layer描述号等信息,根据上面提供的方法算出每帧的长度和每帧持续时间,对于定比特率的其它帧是相同的,也就是说解析第一帧就达到了目的。但这也不是所有情况。变比特率的MPEG文件使用使用所谓比特变换,也就是说每一帧的比特率依照具体内容变化。这时就需要你每一帧都解析。