问题
Using TagLib 1.8 with Qt 5.0.1 on Mac OSX, I'm trying to create a new set of ID3 tags for an AIFF file. The file doesn't have any tags to start with. Here's my code:
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;
The tag
variable is an object from my code holding metadata. concreteTag()
will return a "proper" tag object if the FileRef
returns a TagUnion
from its tag()
function. I've verified that the data in tag
is good.
processID3
will write metadata that is not part of the "basic" fields TagLib supports on the TagLib::Tag
object:
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()));
}
Finally, addId3TextFrame looks like this (I have no images so addID3Images()
is never called):
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));
}
}
My metadata consists (for my current test file) of Album Artist, Track, Genre and Year. At the moment I'm using ID3v2Frame::createTextualFrame()
but I've tried manually creating text frames using correct ID3 frame IDs (TRCK, TCON, etc..)
Here's my problem. TagLib is saving an ID3 v2.4 tag that contains only 1 field - the last field I set. If I reorder my code accordingly, I can make it set any of Album Artist, Track, Genre or Year correctly, but it will only ever save one field.
In the full code, I have a function processMP4, which is very similar to processID3. For MP4 files, all tags are correctly saved. This leads me to believe my approach is sound.
Any ideas what I'm doing wrong?
回答1:
Turns out this was due to compilation settings. By default, CMake on OSX will link to the older GNU libstdc++6 implementation of the standard library. My project is using the new C++11 libc++ implementation.
The interesting part is rather than just dying in a stunningly obvious way (crashing or something), the TagLib code using libstdc++6 was able to read only the first iterator generated by my libc++ code. Furthermore, operator++ on that iterator in libstdc++6 land didn't crash and instead returned end().
来源:https://stackoverflow.com/questions/17007298/taglib-not-saving-id3-tag