我一直试图通过解析mp3文件并检索每个帧的大小来检索ID3V2标记帧。到目前为止,我没有运气。
我已经有效地将内存分配给缓冲区以帮助读取文件,并且已经成功打印出标题版本,但是很难检索到标题和帧大小。对于标题帧大小,我得到1347687723,虽然在十六进制编辑器中查看文件,但我看到05 2B 19。
我的代码的两个片段:
typedef struct{ //typedef structure used to read tag information
char tagid[3]; //0-2 "ID3"
unsigned char tagversion; //3 $04
unsigned char tagsubversion;//4 00
unsigned char flags; //5-6 %abc0000
uint32_t size; //7-10 4 * %0xxxxxxx
}ID3TAG;
if(buff){
fseek(filename,0,SEEK_SET);
fread(&Tag, 1, sizeof(Tag),filename);
if(memcmp(Tag.tagid,"ID3", 3) == 0)
{
printf("ID3V2.%02x.%02x.%02x \nHeader Size:%lu\n",Tag.tagversion,
Tag.tagsubversion, Tag.flags ,Tag.size);
}
}
答案 0 :(得分:2)
由于内存对齐,编译器在标志和大小之间设置了2个字节的填充。如果您的结构直接放在内存中,则大小将位于地址6(从结构的开头)。由于4字节大小的元素必须是4的地址倍数,编译器会添加2个字节,因此 size 会移动到4个地址的最接近的倍数,即8。所以当你读到从您的文件中,大小包含字节8-11。如果您尝试打印 *(& Tag.size - 2),您一定会得到正确的结果。
要解决此问题,您可以逐个阅读字段。
答案 1 :(得分:0)
ID3v2标头结构在所有ID3v2版本(ID3v2.0,ID3v2.3和ID3v2.4)中都是一致的。
其大小存储为 big-endian synch-safe int32
Synchsafe整数是 保持最高位(位7)归零的整数,产生7位 八个可用的。因此,32位同步整数可以存储28 一点点信息。
例:
编码为16位同步整数的255(%11111111)是383 (%00000001 01111111)。
来源:http://id3.org/id3v2.4.0-structure§6.2
下面是一个简单,真实的C#实现,您可以轻松地适应C
public int DecodeSynchSafeInt32(byte[] bytes)
{
return
bytes[0] * 0x200000 + //2^21
bytes[1] * 0x4000 + //2^14
bytes[2] * 0x80 + //2^7
bytes[3];
}
=>使用您在十六进制编辑器(00 05 EB 19)上读取的值,实际标签大小应为112025字节。