ID3V2是目前主流的mp3标签格式,特别是做为车载音乐播放器等一些无法连接到互联网的应用场景上,我们无法通过网络获得歌曲的信息,因此,读取ID3V2或者ID3V1标签就是一个很好的解决方案,这里主要记录的是在qt上通过代码实现这些信息的读取,借鉴了网上主流的方案,这里只是简单的介绍了下代码会用到的地方

一、ID3V2标签格式说明

1.1 标签头

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

char Header[3]; /*必须为"ID3"否则认为标签不存在*/

char Ver; /*版本号;ID3V2.3就记录03,ID3V2.4就记录04*/

char Revision; /*副版本号;此版本记录为00*/

char Flag; /*存放标志的字节,这个版本只定义了三位,稍后详细解说*/

char Size[4]; /*标签大小,包括标签帧和标签头。(不包括扩展标签头的10个字节)*/

我们可以利用Binary Viewer打开任意一个mp3文件:

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(一)

观察前10个字节:

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(一)

其中,49,44,33 对应的ascii码就是ID3,03代表ID3V2.3,说明这个音乐文件的标签是ID3V2.3格式;

后4个字节00,17,2B,1A记录的是整个标签的大小(字节),但每个字节只用7位,最高位不使用恒为0。所以格式如下:

0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx

计算时要做适当的转换,通过移位操作实现:

    mp3_TagSize = 	((Header_size[0] & 0xff) << 21) |
                                ((Header_size[1] & 0xff) << 14) |
                                ((Header_size[2] & 0xff) << 7) |
                                (Header_size[3] & 0xff);

其中Header_size[0]对应的是00字节,Header_size[3]对应的是最后一个字节(1A),以此类推;

1.2标签帧

每个标签帧都有一个10个字节的帧头和至少一个字节的不固定长度的内容组成,如图所示:

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(一)

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(一)

灰色框为帧头,蓝色框为帧内容

帧头的定义如下:

char FrameID[4]; /*用四个字符标识一个帧,说明其内容,稍后有常用的标识对照表*/

char Size[4]; /*帧内容的大小,不包括帧头,不得小于1*/

char Flags[2]; /*存放标志,只定义了6位,稍后详细解说*/

帧内容每个字节的8位全用,格式如下:

xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

framecount = frameSize[0]*0x1000000+frameSize[1]*0x10000+frameSize[2]*0x100+frameSize[3];

1.3 帧标识

用四个字符标识一个帧,说明一个帧的内容含义,常用的对照如下:

TIT2=标题 表示内容为这首歌的标题,下同

TPE1=作者

TALB=专集

TRCK=音轨 格式:N/M 其中N为专集中的第N首,M为专集中共M首,N和M为ASCII码表示的数字

TYER=年代 是用ASCII码表示的数字

TCON=类型 直接用字符串表示

COMM=备注 格式:"eng\0备注内容",其中eng表示备注所使用的自然语言

APIC = 专辑图片

二、图片读取

在网易云音乐和qq音乐下载的歌曲,一般都是以png和jfif(jpeg的一种衍生格式)储存在歌曲文件中的,我们要把图片提取并且存放,就必须知道图片的存储格式,这样才能生成指定的图片文件格式

jpeg格式解析可以参考博文:

https://blog.csdn.net/u012819339/article/details/46544061

png格式解析可以参考博文:

https://blog.csdn.net/bisword/article/details/2777121

我这里只做简单的判断:

png文件标志的前两个字节为89 50;

jpeg文件标志的前两个字节为FF,D8;

根据这两个特点可以判断出图片的类型

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(一)

图中红色部分的14个字节是固定的,我们在读取图片的数据帧时直接跳过,接着到绿色部分,判断绿色部分的数据,根据数据可以得出图片类型,图中显然是jpeg格式图片,接着就可以读取图片内容了(绿色部分也要包含在图片内容的读取部分,红色不用)

总结:在代码中,只要在标签头的10个字节中判断文件开头是否为ID3V2,读取标签的总大小;

然后依次读取每个标签帧;

每个标签帧中又分为:读取标签头,获得标签类型,获得帧内容大小,读取帧内容;

下一篇将通过代码实现读取

QT 读取mp3ID3V2 获取mp3专辑图片、专辑名称、标题、作者(二)

 

 

 

相关文章: