首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++解析ID3V2帧

用C++解析ID3V2帧
EN

Stack Overflow用户
提问于 2017-11-25 17:19:30
回答 3查看 542关注 0票数 0

我一直在尝试通过解析mp3文件并检索每个帧的大小来检索ID3V2标记帧。到目前为止,我还没有运气。

我已经有效地将内存分配给缓冲区以帮助读取文件,并且成功地打印出了标题版本,但在检索标题和帧大小时遇到了困难。对于标题帧大小,我得到1347687723,尽管在十六进制编辑器中查看文件时,我看到的是05 2B 19。

我的两个代码片段:

代码语言:javascript
复制
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);    
    }

}
EN

回答 3

Stack Overflow用户

发布于 2017-11-25 18:34:53

由于内存对齐,编译器在标志大小之间设置了2个字节的填充。如果你的struct是直接放入内存的,那么大小应该在地址6(从struct的开头)。由于4字节大小的元素必须位于4的地址倍数处,因此编译器会添加2个字节,以便大小移动到最接近的4地址的倍数,这里是8。因此,当您从文件中读取时,大小包含字节8-11。如果您尝试打印*(&Tag.size - 2),您肯定会得到正确的结果。

要解决这个问题,您可以一个接一个地读取字段。

票数 2
EN

Stack Overflow用户

发布于 2017-11-26 09:28:32

巧合的是,我也在开发一个ID3V2阅读器。文档说大小是用4个7位字节编码的。因此,您需要另一个步骤将字节数组转换为整数...我不认为仅仅将这些字节作为int读取将会起作用,因为顶部的空位。

票数 0
EN

Stack Overflow用户

发布于 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++

代码语言:javascript
复制
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字节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47484374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档