linux给音乐添加封面,linux系统获取MP3的专辑封面图片

linux系统获取MP3的专辑封面图片

背景

我们播放的MP3格式的音乐的时候,有的显示专辑封面图片,有的不显示,这是为什么呢?是这样的,我们看到的MP3文件不仅仅包含听到的那些声音,其实作为一个MP3文件它还包含描述这首歌的一些文字信息(标题名、作者、专集名、年代、风格等等)和歌词信息,还有内嵌的专辑封面图片等信息。但是并不是所有的MP3文件制作的时候都内嵌了图片,所以有的MP3文件播放的时候,可以显示专辑封面图片,有的不能显示专辑封面图片。一些音乐播放器有修改歌曲封面图片的功能,这里我们来讲一讲怎么自己编写代码(C语言实现)来提取歌曲封面图片。

MP3文件构成

MP3文件(二进制文件)分为三个部分:ID3V2标签、音频数据和ID3V1标签,其中ID3V2标签位于MP3文件的开头,中间为音频数据,ID3V1标签位于MP3文件的结尾。ID3V1只是包含歌曲名、作者、专集名、日期和歌曲风格等基本信息,而ID3V2标签不但包含ID3V1标签的所有信息,还包含专辑封面图片信息,MP3文件的构成如下图所示。

18ad5f292239907517ccd3f90bcda0cd.png

注:封面图片一般是JPEG格式的图片,也有PNG、BMP格式的文件,本文以JPEG格式的图片来讲解,其他格式的原理也是一样的。

实现原理

对MP3二进制文件进行解析,主要是对ID3V2标签进行解析,取得其中的专辑封面图片的数据,然后将图片数据保存为指定类型的图片(通过指定文件扩展名实现),存储到指定路径,需要使用图片的时候,到该路径取得就可以。ID3V2标签的解析下文会详细讲解。

实现方法/步骤

1、打开MP3二进制文件(fopen)

2、取MP3文件前3个字符进行判断,如果为“ID3”,则说明该MP3文件包含ID3V2标签。

3、计算MP3文件数据总的大小,MP3文件的第7~10字节(4个字节)保存MP3文件数据总的大小。

4、取得ID3V2标签帧的帧头

.解析出当前的帧标识,根据这个可以确定MP3数据信息的类别

.计算当前的帧内容的长度,即获得类别信息的大小

5、判断MP3二进制文件中是否有专辑封面图片

如果帧标识为“APIC”,说明MP3中含有专辑封面图片。

6、图片文件格式判断

.jpeg文件标志的前两个字节为FF、D8

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

注:当步骤5判断为有图片的时候,从帧标识为“APIC”的帧头位置开始,如果连续的两个字节为FF和D8,说明这个图片为jpeg文件,即FF、D8是jpeg文件的开始标志。

7、将MP3二进制文件中的图片数据读取出来,保存为jpeg文件

得到了jpeg文件的开始位置(FF、D8),也知道jpeg文件数据的大小,就可将这部分二进制数据取出,保存成扩展名为“XXX.jpeg”的文件。

知识点讲解

以下内容为扩展信息,作为对以上内容的补充说明。

ID3V2标签简介

每个ID3V2的标签都有唯一一个标签头和若干个标签帧组成(每个标签至少要有一个标签帧),标签头和标签帧一起顺序存放在MP3文件的开始位置。MP3的信息如标题、作者、专辑封面图片等都存放在不同的标签帧中。

ID3V2标签头

ID3V2标签头信息位于MP3文件的开始处,长度为10个字节。数据结构如下:

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

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

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

char Flag;      /*存放标志的字节,这个版本只定义了三位,其它位为0*/

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

如下图利用UltraEdit打开一个mp3文件(文件名为“阿福(邓福如)-天使.mp3”):

06a5b4be6caeaf8d3768fcbbe56818cb.png

说明:

1、前3个字节为49,44,33对应的ascii码就是ID3,因此判断存在ID3V2标签

2、第4个字节为03,说明这个音乐文件的标签是ID3V2.3格式

3、第5个字节为00,说明副版本号为0,即版本为ID3V2的3.0版本

4、第6个字节为00,标志字节一般为0,定义如下(abc000000B)

a:表示是否使用Unsynchronisation

b:表示是否有扩展头部,一般没有,所以一般也不设置,默认值为0

c:表示是否为测试标签,99.99%的标签都不是测试标签,不设置,默认值为0

5、第7~10个字节为00,03,48,60,记录的是整个标签的大小(字节数),但每个字节只用7位,最高位不使用恒为0,计算公式如下:

nTagSize = ((size[0] & 0xff) << 21)

|((size[1] & 0xff) << 14)

|((size[2] & 0xff) << 7)

|(size[3] & 0xff);

ID3V2标签帧

每个标签帧都有10个字节的帧头(和ID3V2标签头不是一个东西,虽然他们刚好都是10字节,每个ID3V2标签只有一个标签头,而每个标签帧都有一个帧头,一个ID3V2标签有几个标签帧就会有几个帧头)和至少一个字节的帧内容构成,标签头与标签帧(帧头和帧内容构成)之间无特殊字节分割,只能通过帧头信息来确定帧内容的大小,ID3V2标签帧的构成如下图所示。

0fcbc9f16e7afb4b6c1a8bc029f0f40a.png

帧头

每一个ID3V2标签帧都有一个帧头。

帧头结构

帧头长度10字节,由3部分构成,数据结构如下:

char ID[4];    /*标识帧,说明其内容,例如作者/标题等*/

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

char Flags[2]; /*标志帧,只定义了6 位*/

帧头详细说明

标识帧,常见的内容如下:

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

TPE1 = 作者   表示内容为这首歌的作者

TALB = 专集   表示内容为这首歌的专集

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

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

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

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

APIC = 专辑图片

帧内容

帧头长度为10字节,从帧头标识帧开始位置,向后加10个字节,为该帧内容的开始位置,大小在帧头中已经指定。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值