如何计算MP3的总时长问题(一) | 您所在的位置:网站首页 › 时间MP3 › 如何计算MP3的总时长问题(一) |
MP3是大家所熟悉的一种音乐播放格式,它其实是mpeg标准中的mpeg1的layer3编码,这个是和压缩技术相关的,对于mpeg的了解,大家可以去网上找一些格式解析的文档,在这里我们只要知道MP3这种格式是什么就够了,在以下的内容中,会有详细解释。 MP3中有一个关键词就是:帧,MP3是由若干个帧组成。 1、Mp3的文件结构 MP3文件大体分为三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1),其中ID3V1在整个MP3文件的末尾128个字节,包含了作者,作曲,专辑等信息,而ID3V2是在文件的开头部分,是对ID3V1的扩展包含MP3的一些信息如作者,专辑,发行日等等,它的大小不固定,可以从他的标签头记录的是个字节中得到标识和大小。 char Header[3]; /*必须为"ID3"否则认为标签不存在*/ char Ver; /*版本号ID3V2.3就记录3*/ char Revision; /*副版本号此版本记录为0*/ char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/ char Size[4]; /*标签大小,包括标签头的10个字节和所有的标签帧的大小*/ 我们可以从文件头搜索钱十个字节,判断最初三个字节是否有ID3的标识,如果没有,证明标签头不存在,然后计算标签大小: 一共四个字节,但每个字节只用7位,最高位不使用恒为0。所以格式如下 0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx 计算大小时要将0去掉,得到一个28位的二进制数,就是标签大小(不懂为什么要这样做),计算公式如下: int total_size = (Size[0]&0x7F)*0x200000 +(Size[1]&0x7F)*0x400 +(Size[2]&0x7F)*0x80 +(Size[3]&0x7F) 按道理来说,跳过标签大小,就是第一帧的帧头位置,但是有时候却不是,所以我们仍然要搜索判断是否是帧头,下面我们来看mp3的帧结构。 2、Mp3的帧详解 每一帧其实包括 帧头,附加信息,主数据,其实我们只要找到帧头,帧头中所包含的数据就能让我们掌控这一帧的信息,帧头固定4个字节(32bit),格式如下 AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM 下面是就是每个位置代表的含义: 标识长度含义示例A11用于同步帧,找到此帧头(所有位均置 1)11111111111B2音频版本 ID 00 - 版本是 MPEG 2.5 (MPED-2 的非官方扩展版本) 01 – 保留 10 – 版本是 MPEG 2 (ISO/IEC 13818-3) 11 – 版本是 MPEG 1 (ISO/IEC 11172-3) 通过ID查表得其他信息11C2Layer 的索引 00 – 保留 01 - Layer III 10 - Layer II 11 - Layer I01D1保护位 1 – 无 CRC 0 – 用 16位的 CRC保护下面的帧头1E4比特率索引(查表)1001F2采样率索引 (查表)10G1填充位,如果为1,计算帧长时,要多加11H1私有位 (仅用于标示性的)1I2声道的模式 00 – 立体声 01 – 混合立体声 10 – 双声道 (两个单声道) 11 – 一个声道 (单声道)01J2联合立体声(joint stereo) 采用联合立体声编码方式的两个声道具有关联性。例如MS_stereo将两个声道相加、相差后处理,相减后去掉了左右声道相同的成份,后续的压缩可得到更高的压缩率。10K1版权保护,0=no 1=yes1L1原始版本,0=no 1=yes0M1预加重 00 - none 01 - 50/15 ms 10 - reserved 11 - CCIT J.17011)比特率 其中E和F位置的值,是通过mpeg ID和layer索引查标准的值,我写成了一个数组,直接查表得到比特率 int bitrate[5][15] = { /* MPEG-1 */ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, /* MPEG-2 ,MPEG-2.5 */ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layer */ 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */ }; 2)采样频率: int samplingrate[4][3] = { //value s are in Hz {11025 , 12000 , 8000}, //MPEG Version 2.5 {0,0,0}, //reserved {22050, 24000, 16000}, //MPEG Version 2 (ISO/IEC 13818-3) {44100, 48000, 32000} //MPEG Version 1 (ISO/IEC 11172-3) }; 3)每帧持续时间 在这里在介绍一个比较重要的概念那就是,每帧持续时间,MP3有一个特殊性,那就是每帧持续时间是固定的: 每帧持续时间(毫秒) = 每帧采样数 / 采样频率 * 1000 我们从第一帧的帧头可以得音频版本 ID和layer版本,从而可以确定每帧采样个数 mpeg 1 mpeg 2 mpeg 2.5 layer I 384 384 384 layer II 1152 1152 1152 layer III 1152 576 576 现在我们应该很清楚的知道,为什么我们只需要知道MP3是mpeg1的layerIII层的原因了;(但是按照我现在的理解只要是layer III的就是MP3,呵呵,可以讨论) (写这个有点慢,因为不会用,不知道咋添加表格,不习惯) 4)计算总时长 下面我们来看计算时间的公式: 播放时间 = 总帧bytes ÷ 比特率 × 8000 比特率:查表可得到; 总帧bytes:简单的看就是,总文件的大小-ID3信息,总文件大小就是读取整个文件的大小,ID3就是之前说过的ID3V2和ID3V1,ID3V1在末尾处128个字节,ID3V2在文件开始为止,大小可以从标签头得到,之前讲过,这样我们就能准确的得到总帧bytes,我们就能计算出来mp3的总时长了. 但是这只是对固定比特率(CBR)的MP3总时长的计算方式,对于变比特率(VBR)的MP3,由于每帧的比特率可能不同,用以上的公式就无法准确算出来mp3总时长,有些文档说可以计算平均比特率,但是这个估算值偏差有时候很大,下一次我来详细讲如果求变化比特率Mp3的总时长,牢牢记住上面的表格,一切的信息都能从那里来。 |
CopyRight 2018-2019 实验室设备网 版权所有 |