zoukankan      html  css  js  c++  java
  • MP3: MP3中的ID3v2 格式分析

    一. 基本组成

    MP3文件中的ID3v2 的基本组成如下:

    可以看到,基本分为三部分:标签头帧头帧标识三部分。

    二. 标签头

    在文件的首部顺序记录 10 个字节的 ID3V2.3 的头部。数据结构如下:

    typedef ID3_HEADER {
        uint8_t id3_identifier[3];
        uint8_t id3_version;
        uint8_t id3_revision;
        uint8_t id3_flags;
        uint32_t id3_size;
    } ID3_HEADER_t;

    各个字段的详细含义如下:

    - id3_identifier[3]
      头部标识。占3个字节,由字符ID3组成,表示这是一个ID3v2的标签;
    - id3_version
      主版本号。版本号 ID3V2.3 就记录 3
    - id3_revision
      副版本号。这里记录为0
    - id3_flags
      存放标志的字节。标志字节一般为 0,定义如下: abc00000,
      a -- 表示是否使用 Unsynchronisation(这个单词不知道是什么意思,字典里也没有找到,一般不设置);
      b -- 表示是否有扩展头部,一般没有(至少 Winamp 没有记录),所以一般也不设置
      c -- 表示是否为测试标签(99.99%的标签都不是测试用的啦,所以一般也不设置)

    id3_size
      标签大小。代表的是后面所有标签帧的总大小。一共占四个字节, 但是按照ID3v2 标准(https://id3.org/id3v2.3.0#ID3v2_header)的要求,每个字节只用 7 位,最高位不使用,恒为 0。举个例子来说,
      比如:如果后面标签帧的总大小是257,那么在写入时,就必须是:513

    257 (%00000001  00000001) encoded as a 16 bit synchsafe integer is 513
    (%00000010  00000001).

      又比如:如果后面标签帧的总大小是255,那么在写入时,就必须是:383

    255 (%11111111) encoded as a 16 bit synchsafe integer is 383
    (%00000001 01111111).

      另外,数值在写入时,必须以大端格式写入。 
      由于计算结果需要将每个字节的最高位0位丢弃,所以这里提供两个函数用于处理这个问题:

      丢弃最高位:

    int syncint_encode(int value)
    {
        int out, mask = 0x7F;
    
        while (mask ^ 0x7FFFFFFF)
        {
            out = value & ~mask;
            out <<= 1;
            out |= value & mask;
            mask = ((mask + 1) << 8) - 1;
            value = out;
        }
    
        return out;
    }

      复原:

    int syncint_decode(int value)
    {
        unsigned int a, b, c, d, result = 0x0;
        a = value & 0xFF;
        b = (value >> 8) & 0xFF;
        c = (value >> 16) & 0xFF;
        d = (value >> 24) & 0xFF;
    
        result = result | a;
        result = result | (b << 7);
        result = result | (c << 14);
        result = result | (d << 21);
    
        return result;
    }

    三. 标签帧

    每个标签帧都有一个 10 个字节的帧头和至少一个字节的不固定长度的内容组成。 它们也是顺序存放在文件中,和标签头和其他的标签帧也没有特殊的字符分隔。得到一个完整的帧的内容只有从帧头中的到内容大小后才能读出,读取时要注意大小,不要将其他帧的内容或帧头读入。

    它的数据结构定义如下:

    typedef ID3_FRAME {
        uint8_t frame_id[4];
        uint32_t frame_size;
        uint16_t frame_flags;
    } ID3_FRAME_t;

    各个字段的详细含义如下:
    frame_id[4]。用四个字符标识一个帧,描述其内容,常用的标识有:

      TIT2 = 标题 表示内容为这首歌的标题,下同
      TPE1 = 作者
      TALB = 专集
      TRCK = 音轨 格式:N/M 其中 N 为专集中的第 N 首,M 为专集中共 M 首,N 和 M 为 ASCII 码表示的数字
      TYER = 年代 是用 ASCII 码表示的数字
      TCON = 类型 直接用字符串表示
      COMM = 备注 格式:"eng/0 备注内容",其中 eng 表示备注所使用的自然语言

    更多的标识请参考:https://id3.org/id3v2.3.0#Declared_ID3v2_frames

    frame_size。代表帧内容的大小,这里要注意,写入时也必须为大端格式。

    frame_flags。 代表帧标记暂时不清楚有什么实际含义。


    参考链接:
    1. ID3 tag version 2.4.0 - Main Structure

    2. ID3 tag version 2.3.0(官网)

    3. ID3 Implementations (ID3v2 代码实现)

    4. Mp3(ID3v2)格式文件解析

    5. MP3文件分析之ID3v2.3版本

  • 相关阅读:
    列表
    *
    Model/View
    文件
    提示用户输入并获得输入
    编码
    使用静态QT库编译的程序不显示中文
    rm命令
    高阶函数
    jquery checkbox 操作
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/14990902.html
Copyright © 2011-2022 走看看