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版本

 

posted @ 2021-07-09 15:47  夜行过客  阅读(3259)  评论(0编辑  收藏  举报