之前有写过一篇获取MP3文件tag信息的文章,现在具体说下,tag在MP3文件中只是非常小的一部分信息,专业点的说法是ID3v1标签,其中主要存放了tag信息,现在值得一提的是目前大多数MP3文件中存在的另一种标签ID3v2,这个和ID3v1不同,是存在在MP3文件的开头的,只要这个MP3文件有ID3v2标签,那么一定存在于开头(当然有些没有该标签的MP3文件也并不是不存储信息了,还有别的标签,比如说Xing头,在这里先详细说ID3v2标签),下面看下这些标签的结构吧
整个ID3v2标签分为2个部分:标签头和标签体
标签头:
header ——ID3的标志,占3个byte
version ——版本号,占一个byte
revision ——副版本号,占一个byte
flags ——占一个byte
size ——占4个byte,该size不包括标签头,计算方法:byte_1*0x200000+byte_2*0x4000+byte_3*0x80+byte_4
标签体:
标签体中有很多数据帧,看过MP3文件解析的同学应该知道,数据帧也是和标签头类似的分布:数据帧头和数据帧体
数据帧头:
frame_header
——数据帧的标志,指明该数据帧存放什么数据,占4个byte
frame_size ——数据帧体的大小(不包括帧头),计算方法:byte_1*0x1000000+byte_2*0x10000+byte_3*0x100+byte_4
frame_flags
——占2个字节
frame_encoder
——可能有,在MP3文件解析的介绍上有提到,但是到官网上的ID3v2.3标准格式是没有这个的
数据帧体一般就只有数据,一般是紧跟在数据帧头后面的,但是有一个是例外,就是专辑图片,所以当要获得专辑图片的时候,需要获取图片开始的位置,然后根据计算出来的size大小来读取图片的数据,下面就重点写下图片获取的代码:
public static void GetMediaItemImage(string path)
{
try
{
FileStream fs = new FileStream(path, FileMode.Open);
byte[] header = new byte[10]; //标签头
fs.Read(header, 0, 10);
string head = Encoding.Default.GetString(header, 0, 3);
if (head.Equals("ID3"))
{
int sizeAll = header[6] * 0x200000 //获取该标签的尺寸,不包括标签头
+ header[7] * 0x4000
+ header[8] * 0x80
+ header[9];
int size = 0;
byte[] body = new byte[10]; //数据帧头,这里认为数据帧头不包括编码方式
fs.Read(body, 0, 10);
head = Encoding.Default.GetString(body, 0, 4);
while (!("APIC".Equals(head))) //当数据帧不是图片的时候继续查找
{
size = body[size + 4] * 0x1000000 //获取该数据帧的尺寸(不包括帧头)
+ body[size + 5] * 0x10000
+ body[size + 6] * 0x100
+ body[size + 7];
body = new byte[size + 10];
fs.Read(body, 0, size + 10);
head = Encoding.Default.GetString(body, size, 4);
}
size = body[size + 4] * 0x1000000
+ body[size + 5] * 0x10000
+ body[size + 6] *0x100
+ body[size + 7];
byte[] temp = new byte[4];