zoukankan      html  css  js  c++  java
  • 如何计算MP3总时长的问题(二)

           接着上一次的往下写

    2、Mp3的帧详解 

      每一帧其实包括 帧头,附加信息,主数据,其实我们只要找到帧头,帧头中所包含的数据就能让我们掌控这一帧的信息,帧头固定4个字节(32bit),格式如下

      AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM 

     下面是就是每个位置代表的含义: 

    标识

    长度

    含义

    示例

    A

    11

    用于同步帧,找到此帧头(所有位均置 1)

    11111111111

    B

    2

    音频版本 ID
    00 - 版本是 MPEG 2.5 (MPED-2 的非官方扩展版本)
    01 – 保留
    10 – 版本是 MPEG 2 (ISO/IEC 13818-3)
    11 – 版本是 MPEG 1 (ISO/IEC 11172-3) 通过ID查表得其他信息

    11

    C

    2

    Layer 的索引
    00 – 保留
    01 - Layer III
    10 - Layer II
    11 - Layer I

    01

    D

    1

    保护位
    1 – 无 CRC 0 – 用 16位的 CRC保护下面的帧头

    1

    E

    4

    比特率索引(查表)

    1001

    F

    2

    采样率索引 (查表)

    10

    G

    1

    填充位,如果为1,计算帧长时,要多加1

    1

    H

    1

    私有位 (仅用于标示性的)

    1

    I

    2

    声道的模式
    00 – 立体声
    01 – 混合立体声
    10 – 双声道 (两个单声道)
    11 – 一个声道 (单声道)

    01

    J

    2

    联合立体声(joint stereo) 采用联合立体声编码方式的两个声道具有关联性。

    例如MS_stereo将两个声道相加、相差后处理,相减后去掉了左右声道相同的成份,后续的压缩可得到更高的压缩率。

    10

    K

    1

    版权保护,0=no 1=yes

    1

    L

    1

    原始版本,0=no 1=yes

    0

    M

    1

    预加重 00 - none
    01 - 50/15 ms
    10 - reserved
    11 - CCIT J.17

    01

      1)比特率

    其中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的总时长,牢牢记住上面的表格,一切的信息都能从那里来。

    (才开始写博客,实在不太习惯,写的比较慢,文章继续连载)

  • 相关阅读:
    javascript 面向对象 new 关键字 原型链 构造函数
    前端性能优化之gzip
    电子商务秒杀所带来的问题
    git 远程版本库,github提供服务原理,git自动更新发送邮件
    单点登陆的三种实现方式(详解)
    使用php实现单点登录
    支付宝异步回调
    http状态码大全
    php 单向散列加密
    curl模拟post请求
  • 原文地址:https://www.cnblogs.com/candycaicai/p/1875936.html
Copyright © 2011-2022 走看看