Tag::Tag(const QString &filename) : m_filename(filename) { TagLib::MPEG::File mpegfile(filename.toLocal8Bit().constData()); TagLib::ID3v2::Tag* id3v2 = mpegfile.ID3v2Tag(); if (id3v2 && !id3v2->isEmpty()) { readRegularTag(id3v2, m_data); int picnum = 0; TagLib::ID3v2::FrameList frames = id3v2->frameListMap()["APIC"]; // attached picture TagLib::ID3v2::FrameList::ConstIterator it = frames.begin(); while (it != frames.end()) { TagLib::ID3v2::AttachedPictureFrame* apic = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(*it); TagLib::ByteVector bytes = apic->picture(); QImage img = QImage::fromData(reinterpret_cast<const uchar*>(bytes.data()), bytes.size()); if (!img.isNull()) { m_data[QLatin1String("picture") + QString::number(picnum++)] = QVariant(img); } ++it; } } else { TagLib::FileRef fileref(filename.toLocal8Bit().constData()); if (fileref.isNull()) return; TagLib::Tag* tag = fileref.tag(); if (!tag || tag->isEmpty()) return; readRegularTag(tag, m_data); } }
TagLibTokenizer::TagLibTokenizer(const Document *pDocument) : Tokenizer(NULL), m_pTagDocument(NULL) { if (pDocument != NULL) { Url urlObj(pDocument->getLocation()); string pseudoContent; if ((urlObj.isLocal() == true) && (urlObj.getFile().empty() == false)) { string location(urlObj.getLocation()); string trackTitle; location += "/"; location += urlObj.getFile(); TagLib::FileRef fileRef(location.c_str(), false); if (fileRef.isNull() == false) { TagLib::Tag *pTag = fileRef.tag(); if ((pTag != NULL) && (pTag->isEmpty() == false)) { char yearStr[64]; trackTitle = pTag->title().to8Bit(); trackTitle += " "; trackTitle += pTag->artist().to8Bit(); pseudoContent = trackTitle; pseudoContent += " "; pseudoContent += pTag->album().to8Bit(); pseudoContent += " "; pseudoContent += pTag->comment().to8Bit(); pseudoContent += " "; pseudoContent += pTag->genre().to8Bit(); snprintf(yearStr, 64, " %u", pTag->year()); pseudoContent += yearStr; } } else { trackTitle = pseudoContent = pDocument->getTitle(); } m_pTagDocument = new Document(trackTitle, pDocument->getLocation(), pDocument->getType(), pDocument->getLanguage()); m_pTagDocument->setData(pseudoContent.c_str(), pseudoContent.length()); m_pTagDocument->setTimestamp(pDocument->getTimestamp()); m_pTagDocument->setSize(pDocument->getSize()); // Give the result to the parent class setDocument(m_pTagDocument); } } }
void TagLibExtractor::extract(ExtractionResult* result) { const QString fileUrl = result->inputUrl(); const QString mimeType = result->inputMimetype(); TagLib::FileRef file(fileUrl.toUtf8().constData(), true); if (file.isNull()) { return; } TagLib::Tag* tags = file.tag(); result->addType(Type::Audio); TagLib::String artists; TagLib::String albumArtists; TagLib::String composers; TagLib::String lyricists; TagLib::StringList genres; // Handling multiple tags in mpeg files. if ((mimeType == QLatin1String("audio/mpeg")) || (mimeType == QLatin1String("audio/mpeg3")) || (mimeType == QLatin1String("audio/x-mpeg"))) { TagLib::MPEG::File mpegFile(fileUrl.toUtf8().constData(), true); if (mpegFile.ID3v2Tag() && !mpegFile.ID3v2Tag()->isEmpty()) { TagLib::ID3v2::FrameList lstID3v2; // Artist. lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["TPE1"]; if (!lstID3v2.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { if (!artists.isEmpty()) { artists += ", "; } artists += (*it)->toString(); } } // Album Artist. lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["TPE2"]; if (!lstID3v2.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { if (!albumArtists.isEmpty()) { albumArtists += ", "; } albumArtists += (*it)->toString(); } } // Composer. lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["TCOM"]; if (!lstID3v2.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { if (!composers.isEmpty()) { composers += ", "; } composers += (*it)->toString(); } } // Lyricist. lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["TEXT"]; if (!lstID3v2.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { if (!lyricists.isEmpty()) { lyricists += ", "; } lyricists += (*it)->toString(); } } // Genre. lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()["TCON"]; if (!lstID3v2.isEmpty()) { for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) { genres.append((*it)->toString()); } } } } // Handling multiple tags in Ogg containers. { TagLib::Ogg::FieldListMap lstOgg; // FLAC files. if (mimeType == QLatin1String("audio/flac")) { TagLib::FLAC::File flacFile(fileUrl.toUtf8().constData(), true); if (flacFile.xiphComment() && !flacFile.xiphComment()->isEmpty()) { lstOgg = flacFile.xiphComment()->fieldListMap(); } } // Vorbis files. if (mimeType == QLatin1String("audio/ogg") || mimeType == QLatin1String("audio/x-vorbis+ogg")) { TagLib::Ogg::Vorbis::File oggFile(fileUrl.toUtf8().constData(), true); if (oggFile.tag() && !oggFile.tag()->isEmpty()) { lstOgg = oggFile.tag()->fieldListMap(); } } // Opus files. if (mimeType == QLatin1String("audio/opus") || mimeType == QLatin1String("audio/x-opus+ogg")) { TagLib::Ogg::Opus::File opusFile(fileUrl.toUtf8().constData(), true); if (opusFile.tag() && !opusFile.tag()->isEmpty()) { lstOgg = opusFile.tag()->fieldListMap(); } } // Handling OGG container tags. if (!lstOgg.isEmpty()) { TagLib::Ogg::FieldListMap::ConstIterator itOgg; // Artist. itOgg = lstOgg.find("ARTIST"); if (itOgg != lstOgg.end()) { if (!artists.isEmpty()) { artists += ", "; } artists += (*itOgg).second.toString(", "); } // Album Artist. itOgg = lstOgg.find("ALBUMARTIST"); if (itOgg != lstOgg.end()) { if (!albumArtists.isEmpty()) { albumArtists += ", "; } albumArtists += (*itOgg).second.toString(", "); } // Composer. itOgg = lstOgg.find("COMPOSER"); if (itOgg != lstOgg.end()) { if (!composers.isEmpty()) { composers += ", "; } composers += (*itOgg).second.toString(", "); } // Lyricist. itOgg = lstOgg.find("LYRICIST"); if (itOgg != lstOgg.end()) { if (!lyricists.isEmpty()) { lyricists += ", "; } lyricists += (*itOgg).second.toString(", "); } // Genre. itOgg = lstOgg.find("GENRE"); if (itOgg != lstOgg.end()) { genres.append((*itOgg).second); } } } // Handling multiple tags in Musepack files. if (mimeType == QLatin1String("audio/x-musepack")) { TagLib::MPC::File mpcFile(fileUrl.toUtf8().constData(), true); if (mpcFile.tag() && !mpcFile.tag()->isEmpty()) { TagLib::APE::ItemListMap lstMusepack = mpcFile.APETag()->itemListMap(); TagLib::APE::ItemListMap::ConstIterator itMPC; // Artist. itMPC = lstMusepack.find("ARTIST"); if (itMPC != lstMusepack.end()) { if (!artists.isEmpty()) { artists += ", "; } artists += (*itMPC).second.toString(); } // Album Artist. itMPC = lstMusepack.find("ALBUMARTIST"); if (itMPC != lstMusepack.end()) { if(!albumArtists.isEmpty()) { albumArtists += ", "; } albumArtists += (*itMPC).second.toString(); } // Composer. itMPC = lstMusepack.find("COMPOSER"); if (itMPC != lstMusepack.end()) { if (!composers.isEmpty()) { composers += ", "; } composers += (*itMPC).second.toString(); } // Lyricist. itMPC = lstMusepack.find("LYRICIST"); if (itMPC != lstMusepack.end()) { if (!lyricists.isEmpty()) { lyricists += ", "; } lyricists += (*itMPC).second.toString(); } // Genre. itMPC = lstMusepack.find("GENRE"); if (itMPC != lstMusepack.end()) { genres.append((*itMPC).second.toString()); } } } if (!tags->isEmpty()) { QString title = t2q(tags->title()); if (!title.isEmpty()) { result->add(Property::Title, title); } QString comment = t2q(tags->comment()); if (!comment.isEmpty()) { result->add(Property::Comment, comment); } if (genres.isEmpty()) { genres.append(tags->genre()); } for (uint i = 0; i < genres.size(); i++) { QString genre = t2q(genres[i]).trimmed(); // Convert from int bool ok = false; int genreNum = genre.toInt(&ok); if (ok) { genre = t2q(TagLib::ID3v1::genre(genreNum)); } result->add(Property::Genre, genre); } QString artistString; if (artists.isEmpty()) { artistString = t2q(tags->artist()); } else { artistString = t2q(artists).trimmed(); } QStringList artists = contactsFromString(artistString); foreach(const QString& artist, artists) { result->add(Property::Artist, artist); }
int main (int argc, char *argv[]) { try { static struct option long_options[] = { { "source-encoding", required_argument, NULL, 's' }, { "id3v1-encoding", required_argument, NULL, '1' }, { "id3v2-encoding", required_argument, NULL, '2' }, { "preserve-unicode", no_argument, NULL, 'p' }, { "preview", no_argument, NULL, 'w' }, { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, { "quiet", no_argument, NULL, 'q' }, { NULL, 0, NULL, 0 } }; int long_options_ret; std::string source_encoding; std::string id3v1_encoding = "none"; std::string id3v2_encoding = "none"; bool preserve_unicode = false; bool preview = false; bool usage_ok = true; bool verbose = true; if(argc == 1) { printf("%s", msg::usage); exit(1); } while ( (long_options_ret = getopt_long (argc, argv, "s:1:2:pwdvhq", long_options, NULL)) != -1 ) { switch (long_options_ret) { case 's': source_encoding = optarg; tolower(source_encoding); break; case '1': id3v1_encoding = optarg; tolower(id3v1_encoding); break; case '2': id3v2_encoding = optarg; tolower(id3v2_encoding); break; case 'p': preserve_unicode = true; break; case 'w': preview = true; break; case 'v': printf("%s %s\n", PACKAGE, PACKAGE_VERSION); printf("%s", msg::copyright); exit (1); break; case 'h': printf("%s", msg::usage); exit(1); case 'q': verbose = false; break; default: usage_ok = false; break; } } if (usage_ok && source_encoding.empty ()) { printf("%s", msg::nosenc); usage_ok = false; } if(optind == argc) { printf("%s", msg::nofiles); usage_ok = false; } if (!usage_ok) { printf("%s", msg::seehelp); exit (1); } TagLib::ID3v2::FrameFactory::instance()->setDefaultTextEncoding (TagLib::String::UTF8); for (int i=optind;i<argc;i++) { TagLib::MPEG::File mp3file(argv[i]); if (!mp3file.isOpen ()) { throw msg::nofile(argv[i]); } TagLib::Tag *tag = mp3file.tag(); if(tag->isEmpty()) { printf("%s", msg::emptyfile(argv[i]).c_str()); } else { Converter converter ( source_encoding, id3v1_encoding, id3v2_encoding, mp3file.ID3v1Tag (true), mp3file.ID3v2Tag (true), preserve_unicode ); converter.Convert (tag->title (), &TagLib::Tag::setTitle); converter.Convert (tag->artist (), &TagLib::Tag::setArtist); converter.Convert (tag->album (), &TagLib::Tag::setAlbum); converter.Convert (tag->comment (), &TagLib::Tag::setComment); converter.Convert (tag->genre (), &TagLib::Tag::setGenre); if (preview) { converter.printTags(argv[i]); } else { mp3file.strip(~converter.Tags()); if (!mp3file.save (converter.Tags ())) { printf("%s", msg::writefail(argv[i]).c_str()); } else if(verbose) { printf("%s", msg::filedone(argv[i]).c_str()); } } } } exit (0); } catch (const std::string &e) { printf ("%s", msg::error(e).c_str()); exit (1); } catch (const char *e) { printf ("%s", msg::error(e).c_str()); exit (1); } return 1; }