在 C++ 中读取 mp3 id3 标签

Posted

技术标签:

【中文标题】在 C++ 中读取 mp3 id3 标签【英文标题】:read mp3 id3 tags in C++ 【发布时间】:2014-07-05 09:26:26 【问题描述】:

我尝试读取 id3 标签的标题:

int main() 

    union MP3Header 
        char header[10];
        struct HeaderStruct 
        char tagIndicator[3];
        char version[2];
        char flags[1];
        char size[4];
       headerStruct;
    ;


    fstream file;
    file.open("file.mp3", ios::binary || ios::in);

    MP3Header header;
    //read header of id3
    file.read(header.header, 10);


    //tag description
    char tag[4] = 0;
    strncpy(tag, header.headerStruct.tagIndicator, 3);
    cout << tag << endl;


    //get size
    string sizeTags = "";
    for (int i=0; i<4; i++) 
        bitset<8> bit_set = header.headerStruct.size[i];
        sizeTags += bit_set.to_string();
    
    cout << sizeTags << endl;

对于某些 mp3 文件,标签大小为 ... 1111101110110(8054 字节) 我认为这段代码是错误的,因为大小很奇怪。

【问题讨论】:

A simple search 或检查规范会确认您希望 128B 作为标准配置或 227B 扩展。您应该使用类似的库,例如id3lib。 id3 标签位于 MP3 文件的末尾,而不是头部。 id3v2 是头部。感谢 lib。 您的号码可能没问题,但只需要转换,因为 MP3 使用同步安全整数。看到这个:SynceSafe Integer conversion 【参考方案1】:

总结一下我的失眠咆哮......

转到第 7 个字节 读取一个整数(也就是四个字节) 通过“synchSafe 转换器”函数传递该金额 结果现在是正确的标头大小(减去 10 个字节)

我使用 AS3,但我也学习 C++、C#、Java、php、Python 等代码,然后将它们的代码逻辑转换为 AS3。现在我将向您展示我们如何在 Flash (AS3) 中做到这一点,也许您可​​以将其转换为 C++。

(用于签入 ID3 v2 以上)

mp3_Bytes.position = 6; //go to 7th byte (offset 6) for Header Size bytes (integer)
mp3_headerLength = readSynchsafeInt ( mp3_Bytes.readUnsignedInt() );

mp3_headerLength +=  10; //add 10 cos result always seems to be 10 bytes less
trace("Header Length  : " + mp3_headerLength);

用于转换读取的 Int(四个字节)的同步安全函数如下所示:

private function readSynchsafeInt (synch:int):int

   return (synch & 127) + 128 * ((synch >> 8) & 127) + 16384 * ((synch >>16) & 127) + 2097152 * ((synch >> 24) & 127);

我为您快速查找并找到了这个 C++:Why are there Synchsafe Integer? 同步安全功能看起来像

int ID3_sync_safe_to_int( uint8_t* sync_safe )

    uint32_t byte0 = sync_safe[0];
    uint32_t byte1 = sync_safe[1];
    uint32_t byte2 = sync_safe[2];
    uint32_t byte3 = sync_safe[3];

    return byte0 << 21 | byte1 << 14 | byte2 << 7 | byte3;

顺便说一句:AS3 函数恰好是为转换整数字节的总和而构建的,而 C++ 代码示例正在处理实际的整数字节。相同结果的两种不同方法。选择一个(AS3 转换从字节获得的数字 = 结果或 C++ 将字节转换为获得数字 = 结果)

【讨论】:

以上是关于在 C++ 中读取 mp3 id3 标签的主要内容,如果未能解决你的问题,请参考以下文章

正确读取被 ID3 标签破坏的 MP3 文件

读取远程 mp3 文件的 ID3 标签?

使用 JavaFX MediaPlayer 从 MP3 读取 ID3v2 标签

javascript:从 mp3 流中读取 id3 标签

通过javascript从文件夹中的mp3文件中读取id3标签

在 MP3 ID3v2 标签中设置歌词