2013-06-09 1 views
1

Используя TagLib 1.8 с Qt 5.0.1 на Mac OSX, я пытаюсь создать новый набор тегов ID3 ​​для файла AIFF. Файл не имеет никаких тегов для начала. Вот мой код:TagLib не сохраняет тег 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 является объектом моего кода, проведение метаданных. concreteTag() вернет «правильный» объект тега, если FileRef возвращает TagUnion из его функции tag(). Я проверял, что данные в tag хороши.

processID3 будет записывать метаданные, которые не является частью «основных» полого TagLib поддерживает на TagLib::Tag объекте:

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(), но я попытался вручную создать текстовые фреймы с использованием правильных ID ID-кадров (TRCK, TCON и т. Д.)

Вот моя проблема. TagLib сохраняет тег ID3 v2.4, который содержит только 1 поле - последнее поле, которое я установил. Если я переупорядочу свой код соответствующим образом, я могу настроить его для любого исполнителя альбома, трека, жанра или года правильно, но он сохранит только одно поле.

В полном коде у меня есть функция processMP4, которая очень похожа на processID3. Для файлов MP4 все теги сохранены правильно. Это заставляет меня поверить, что мой подход звучит.

Любые идеи, что я делаю неправильно?

ответ

0

Оказывается, это связано с настройками компиляции. По умолчанию CMake на OSX будет ссылаться на версию GNU libstdC++ 6 стандартной библиотеки. Мой проект использует новую реализацию C++ 11 libC++.

Интересная часть, а не просто умирающая потрясающе очевидным образом (сбой или что-то еще), код TagLib с использованием libstdC++ 6 смог прочитать только первый итератор, сгенерированный моим кодом libC++. Более того, оператор ++ на этом итераторе в libstdC++ 6 не разбился и вместо этого вернулся end().