
MP3 文件格式解析 -- 速通版
对有一定音视频基础知识的人群,可参考本文快速了解MP3文件的一些重点信息和内容。
前排提示:之所以叫 “速通版”,前提是对有一定音视频基础知识的人群,可参考本文快速了解一些重点信息和内容。
目录
整体结构
整体来看,MP3 文件数据是由多个帧组成,帧是 MP3 文件最小组成单位。
每个帧又由 帧头、附加信息、声音数据 组成。
每个帧播放时间是 0.026 秒,其长度随位率的不同而不等。
MP3 文件结构主要有 3 个部分(文件顺序从前到后):
ID3V2 | 音频数据 | ID3V1 |
历史原因:较早时期的 ID3V1 规定是记录在文件的末尾处的,长度固定大小。等到后来新的 ID3V2 就只能记录在文件的首部。所以,ID3V2 比 ID3V1 的结构复杂,可以记录更多的信息,其长度大小可变。
ID3V2
位于首部,支持 4 个版本,最常见的版本是 ID3V2.3;
长度不固定,扩展了 ID3V1 的信息;
由一个标签头和若干个标签帧或者一个扩展标签头组成;
至少要有一个标签帧,每一个标签帧记录一种信息,例如作曲、标题等。
音频数据(重点部分)
由一系列数据帧组成,数据帧 = 帧头 + 数据实体;
- 帧头,长度是 4 个字节,记录 MP3 帧率、采样率、版本信息,声道模式等;
帧头的结构体定义中,主要成员如下:
取值类型 | 名称 | 占位大小 | 说明 |
unsigned int | sync | 11bit; | 同步信息 (固定值,全为 1) |
unsigned int | version | 2bit | 版本 (e.g. 值 11,表示 MPEG1) |
unsigned int | layer | 2bit | 层 (e.g. 值 01,表示 Layer3) |
unsigned int | error protection: | 1bit | 标识在帧头后面是否有长度 2 字节的 CRC 校验数据: 0-无校验,1-有校验 |
unsigned int | bitrate_index | 4bit | 位率(同一个值所表示的意义根据上面 version 和 layer 标准而各有不同。 e.g. 值 0101,MPEG1-Layer3 是 60 Kbps,MPEG2-Layer2 是 80 Kbp) |
- 帧大小与长度的计算
帧大小,即每帧的采样数,表示一帧数据中采样的个数,该值根据标准有对应的值(e.g. MPEG1-Layer3 是 1152);
帧长度,是压缩时每一帧的长度,包括帧头的 4 个字节和填充的空位长度(Layer 1每个空位长 4 字节,Layer 2/3每个空位是 1 字节); 当读取 MPEG 文件时必须计算该值以便找到相邻的帧。 注意:因为有填充和比特率变换,帧长度可能变化。 计算公式如下:
Layer 1:Len(字节) = ((每帧采样数 / 8 * 比特率) / 采样频率) + 填充 * 4
Layer2/3:Len(字节) = ((每帧采样数 / 8 * 比特率) / 采样频率) + 填充
e.g. MPEG1 Layer3 比特率 128Kbps,采样率44100 Hz,填充0,则计算出来的帧长度为:
((1152 / 8 * 128 K) / 44.1 K) + 0 = 417 字节
- 附加信息(Side Info)
长度可变。标准的立体声 MP3 文件,长度为 32 字节。
当解码器在读到上述信息后,就可以进行解码了。不同的解码方式对应不同的编码, MP3 有 2 种压缩的编码方式:
① CBR:Constant BiteRate,固定位率
帧的大小在整个文件中都是是固定的(公式如上所述),所以,只要知道文件总长度,从第一帧的帧头读出的信息,就都可以通过计算得出整个mp3文件的更多信息,比如总的帧数,总的播放时间等。
在Seek操作时,可以很方便的定位到某一帧或某个时间点,因为不需要文件头,第一帧开始就是音频数据。
② VBR:Variable BiteRate, 可变位率
是 XING 公司推出的算法,在 MP3 文件中的第一个 "有效帧" 的数据区里会有 "Xing" 这个关键字(也有用"Info"来标识的),它标识了这个 MP3 文件是 VBR 的。
同时第一个帧里存放了 MP3 文件的帧的总个数,这就很容易获得了播放总时间,同时还有 100 个字节存放了播放总时间的 100 个时间分段的帧索引 index。
假设 4 分钟的 MP3 歌曲,时长 240 sec,分成100段,每两个相邻INDEX的时间差就是 2.4 s。 所以,通过这个 index,只要前后处理少数的帧,就能快速找出需要快进的帧头。
这里的第一帧就相当于文件头的概念。 不过,有的编码器(e.g. 比较有名的 lame, 用 "Info" 来做 CBR 的标记)在编码 CBR 文件时也将信息记入第一帧。
ID3V1
在 MP3 文件结尾, 固定大小 128 字节。主要是包含了作者,作曲专辑等信息。
PS:分享
一个系统深入学习音视频知识的课程 —— https://xxetb.xetslk.com/s/45jaSl
(学无止境,文章如有纰漏不足,欢迎您不吝指正!谢谢 ^_^)
更多推荐
所有评论(0)