TagLib 不保存 ID3 标签

Posted

技术标签:

【中文标题】TagLib 不保存 ID3 标签【英文标题】:TagLib not saving ID3 tag 【发布时间】:2013-06-09 07:10:04 【问题描述】:

在 Mac OSX 上使用 TagLib 1.8 和 Qt 5.0.1,我正在尝试为 AIFF 文件创建一组新的 ID3 标记。该文件没有任何标签开头。这是我的代码:

TagLib::Tag *t = concreteTag();

assert(tag);

if (t) 
        auto id3Tag = dynamic_cast<TagLib::ID3v2::Tag *>(t);

        t -> setTitle(QStringToTagLib(tag -> title()));
        t -> setAlbum(QStringToTagLib(tag -> album()));
        t -> setComment(QStringToTagLib(tag -> comment()));
        t -> setYear(tag -> year());

        if (id3Tag)
                processID3(id3Tag, tag);

        return m_file.save();
   

return false;

tag 变量是我的代码中保存元数据的对象。如果FileRef 从其tag() 函数返回TagUnionconcreteTag() 将返回一个“正确的”标签对象。我已经验证tag中的数据是好的。

processID3 将在 TagLib::Tag 对象上写入不属于 TagLib 支持的“基本”字段的元数据:

processID3(TagLib::ID3v2::Tag *dst, TagSP src) const 
        addID3Images(dst, src -> albumArt());
        addId3TextFrame(dst, "ALBUMARTIST", src -> albumArtist());
        addId3TextFrame(dst, "ARTIST", src -> artists());
        addId3TextFrame(dst, "GENRE", src -> genres());
        addId3TextFrame(dst, "COMPOSER", src -> composers());

        if (src -> track() > 0) 
                if (src -> totalTracks() > 0)
                        addId3TextFrame(dst, "TRACKNUMBER", QString(src -> track()) + "/" + src -> totalTracks());
                else
                        addId3TextFrame(dst, "TRACKNUMBER", QString(src -> track()));
        

        if (src -> disc() > 0) 
                if (src -> totalDiscs() > 0)
                        addId3TextFrame(dst, "DISCNUMBER", QString(src -> disc()) + "/" + src -> totalDiscs());
                else
                        addId3TextFrame(dst, "DISCNUMBER", QString(src -> disc()));
        

最后,addId3TextFrame 看起来像这样(我没有图像,所以永远不会调用 addID3Images()):

void addId3TextFrame(TagLib::ID3v2::Tag *tag, const char *type, const QStringList& value) 
        if (!value.isEmpty()) 
                TagLib::StringList sl;

                for (auto it = value.begin(); it != value.end(); it++) 
                        if (!it -> isEmpty())
                        sl.append(QStringToTagLibID3(*it));
                

                tag -> removeFrames(type);
                tag -> addFrame(TagLib::ID3v2::Frame::createTextualFrame(type, sl));
        

我的元数据包括(对于我当前的测试文件)专辑艺术家、曲目、流派和年份。目前我正在使用ID3v2Frame::createTextualFrame(),但我尝试使用正确的 ID3 框架 ID(TRCK、TCON 等)手动创建文本框架。

这是我的问题。 TagLib 正在保存一个仅包含 1 个字段的 ID3 v2.4 标记 - 我设置的最后一个字段。如果我相应地重新排序我的代码,我可以让它正确设置专辑艺术家、曲目、流派或年份中的任何一个,但它只会保存一个字段。

在完整代码中,我有一个函数processMP4,它与processID3非常相似。对于 MP4 文件,所有标签均已正确保存。这让我相信我的方法是合理的。

任何想法我做错了什么?

【问题讨论】:

【参考方案1】:

原来这是由于编译设置造成的。默认情况下,OSX 上的 CMake 将链接到标准库的旧 GNU libstdc++6 实现。我的项目正在使用新的 C++11 libc++ 实现。

有趣的是,使用 libstdc++6 的 TagLib 代码不仅仅是以一种非常明显的方式死去(崩溃或其他什么),它只能读取我的 libc++ 代码生成的第一个迭代器。此外,libstdc++6 中该迭代器上的 operator++ 没有崩溃,而是返回了 end()。

【讨论】:

以上是关于TagLib 不保存 ID3 标签的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 taglib 将图片添加到 ID3 相册标签#

使用 taglib-sharp 删除 ID3 标签的所有图片

调整 ID3 标签图片大小

RoR TagLib-Ruby:如何在 DB 中设置 ID3 标签

ID3标签提取

使用 taglib# 提取 mp3 标签