我一直在尝试通过解析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);
}
}发布于 2017-11-25 18:34:53
由于内存对齐,编译器在标志和大小之间设置了2个字节的填充。如果你的struct是直接放入内存的,那么大小应该在地址6(从struct的开头)。由于4字节大小的元素必须位于4的地址倍数处,因此编译器会添加2个字节,以便大小移动到最接近的4地址的倍数,这里是8。因此,当您从文件中读取时,大小包含字节8-11。如果您尝试打印*(&Tag.size - 2),您肯定会得到正确的结果。
要解决这个问题,您可以一个接一个地读取字段。
发布于 2017-11-26 09:28:32
巧合的是,我也在开发一个ID3V2阅读器。文档说大小是用4个7位字节编码的。因此,您需要另一个步骤将字节数组转换为整数...我不认为仅仅将这些字节作为int读取将会起作用,因为顶部的空位。
发布于 2017-11-29 15:28:38
所有ID3v2版本(ID3v2.0、ID3v2.3和ID3v2.4)的ID3v2报头结构都是一致的。
它的大小存储为大端同步安全的int32
同步安全整数是保持其最高位(第7位)为零的整数,从而使8位中的7位可用。因此,32位同步安全整数可以存储28位信息。
示例:
编码为16位同步安全整数的255 (%11111111)为383 (%00000001 01111111)。
来源:§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];
}=>使用您在十六进制编辑器中读取的值(005EB19),实际标记大小应为112025字节。
https://stackoverflow.com/questions/47484374
复制相似问题