MP3文件格式分析
Posted alen_xie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MP3文件格式分析相关的知识,希望对你有一定的参考价值。
ID3V2ID3V2 到现在一共有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*/
char Revision; /*副版本号此版本记录为0*/
char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/
char Size[4]; /*标签大小,包括标签头的10 个字节和所有的标签帧的大小*/
1)标志字节
标志字节一般为0,定义如下:
abc00000
a -- 表示是否使用Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置)
b -- 表示是否有扩展头部,一般没有(至少Winamp 没有记录),所以一般也不设置
c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)
第6个字节:存放标志的字节,只定义了三位,这里值为0
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)
第7到10字节:表示ID3标签的大小,这里为
total_size=(0x00&0x7F)*0x200000+(0x00&0x7F)*0x400+(0x2F&0x10)*0x80 +(0x76 &072)
= 0x872 =2162
注意:这里的帧大小,并不包含帧头的10个字节,只表示帧内容的大小
2、标签帧
每个标签帧都有一个10 个字节的帧头和至少一个字节的不固定长度的内容组成。它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。
帧头的定义如下:
char ID[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 表示备注所使用的自然语言
注:更多的帧标识说明见附录一。
前4个字节为帧标识,这里是54 49 5432(TIT2) 是标题的标签帧
2)大小
这个可没有标签头的算法那么麻烦,每个字节的8 位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x100000000 + Size[1]*0x10000+ Size[2]*0x100 + Size[3];
第5到8字节为标签帧的大小,这里为
FSize = 0x00*0x100000000+ 0x00*0x10000 + 0x00*0x100 + 0x24 = 0x24 = 36
注意:这里的帧大小,并不包含帧头的10个字节,只表示帧内容的大小
3)标志
只定义了6 位,另外的10 位为0,但大部分的情况下16 位都为0 就可以了。格式如下:
abc00000ijk00000
a -- 标签保护标志,设置时认为此帧作废
b -- 文件保护标志,设置时认为此帧作废
c -- 只读标志,设置时认为此帧不能修改(但我没有找到一个软件理会这个标志)
i -- 压缩标志,设置时一个字节存放两个BCD 码表示数字
j -- 加密标志(没有见过哪个MP3 文件的标签用了加密)
k -- 组标志,设置时说明此帧和其他的某帧是一组
值得一提的是winamp 在保存和读取帧内容的时候会在内容前面加个''\\0'',并把这个字节计算在帧内容的大小中。
2、音频数据帧
每个帧都有一个帧头Header,长度是4Byte(32bit),帧头后面可能有两个字节的CRC 校验值,这两个字节的是否存在决定于Header 信息的第16bit,为0 则帧头后面无校验,为1 则有校验,校验值长度为2 个字节,紧跟在Header 后面,接着就是帧的实体数据了,格式如下:
1、 帧头格式
帧头长4字节,对于固定位率的MP3文件,所有帧的帧头格式一样其数据结构如下(注:此结构要自己定义):
typedef struct frameHeader
unsigned int sync1:8; //同步信息1
unsigned int error_protection:1; //CRC校验
unsigned int layer:2; //层
unsigned int version:2; //版本
unsigned int sync2:3; //同步信息2
unsigned int extension:1; //版权
unsigned int padding:1; //填充空白字
unsigned int sample_rate_index:2; //采样率索引
unsigned int bit_rate_index:4; //位率索引
unsigned int emphasis:2; //强调方式
unsigned int original:1; //原始媒体
unsigned int copyright:1; //版权标志
unsigned int mode_extension:2; //扩展模式,仅用于联合立体声
unsigned int channel_mode:2; //声道模式
FHEADER, *LPHEADER;
也就是下面的格式:
表1 MP3帧头字节使用说明
名称 | 位长 | 说 明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
同步信息 | 11 | 第1、2字节 | 所有位均为1,第1字节恒为FF。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
版本 | 2 | 00-MPEG 2.5 01-未定义 10-MPEG 2 11-MPEG 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
层 | 2 | 00-未定义 01-Layer 3 10-Layer 2 11-Layer 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CRC校验 | 1 | 0-校验 1-不校验 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
位率 | 4 | 第3字节 |
取样率,单位是
kbps
,例如采用
MPEG-1 Layer 3
,
64kbps
是,值为
0101
。
L1 - Layer 1 L2 - Layer 2 L3 - Layer 3 "free" 表示位率可变 "bad" 表示不允许值 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
采样频率 | 2 | 采样频率,对于 MPEG-1 : 00-44.1kHz 01-48kHz 10-32kHz 11- 未定义 对于 MPEG-2 : 00-22.05kHz 01-24kHz 10-16kHz 11- 未定义 对于 MPEG-2.5 : 00-11.025kHz 01-12kHz 10-8kHz 11- 未定义 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
帧长调节 | 1 | 用来调整文件头长度,0-无需调整,1-调整,具体调整计算方法见下文。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
保留字 | 1 | 没有使用。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
声道模式 | 2 | 第4字节 | 表示声道, 00-立体声Stereo 01-Joint Stereo 10-双声道 11-单声道 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
扩充模式 | 2 |
当声道模式为
01
是才使用。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
版权 | 1 | 文件是否合法,0-不合法 1-合法 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
原版标志 | 1 | 是否原版, 0-非原版 1-原版 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
强调方式 | 2 | 用于声音经降噪压缩后再补偿的分类,很少用到,今后也可能不会用。 00- 未定义 01-50/15ms 10- 保留 11-CCITT J.17 |
MP3帧长取决于位率和频率,计算公式为:
. mpeg1.0 layer1 : 帧长= (48000*bitrate)/sampling_freq + padding
layer2&3: 帧长= (144000*bitrate)/sampling_freq + padding
. mpeg2.0 layer1 : 帧长= (24000*bit
以上是关于MP3文件格式分析的主要内容,如果未能解决你的问题,请参考以下文章