oopapidocs  2.0
tmetadataloader.cpp
00001 #include <QtCore>
00002 #include <taglib/mpegfile.h>
00003 #include <taglib/fileref.h>
00004 #include <taglib/id3v2tag.h>
00005 #include <taglib/id3v2frame.h>
00006 #include "tmetadataloader.h"
00007 #include "preference.h"
00008 
00009 using namespace TagLib;
00010 
00015 class MetaDataFunctor : public std::unary_function<QString, MetaDataValue> {
00016 public:
00017     MetaDataValue operator()(QString path);
00018 };
00019 
00020 
00021 QString toQString(const TagLib::String &s) {
00022 #ifdef Q_OS_WIN
00023     return QString::fromAscii(s.toCString());
00024 #else
00025     return QString::fromStdWString(s.toWString());
00026 #endif
00027 }
00028 
00029 const QString FMPSPREFIX="[FMPS_Rating] FMPS_Rating ";
00030 QRegExp fmpsRx("FMPS_Rating ([\\d\\.]+)");
00031 //start id="functor"
00032 MetaDataValue MetaDataFunctor::operator ()(QString path) {
00033     using namespace TagLib;
00034     MetaDataValue retval;
00035     FileRef f(path.toLocal8Bit().constData());
00036     const Tag* t = f.tag();
00037     Q_ASSERT( t != NULL ) ;
00038     retval.setFileName(path);
00039     retval.setTrackTitle(toQString(t->title()));
00040     retval.setArtist(toQString(t->artist()));
00041     retval.setAlbumTitle(toQString(t->album()));
00042 //end
00043     QString trackNumber = QString("%1").arg(t->track());
00044     retval.setTrackNumber(trackNumber);
00045     retval.setGenre(toQString(t->genre()));
00046     retval.setComment(toQString(t->comment()));
00047 #ifdef FMPS_RATING
00048     // http://www.freedesktop.org/wiki/Specifications/free-media-player-specs
00049     MPEG::File mpegFile(path.toLocal8Bit());
00050     const ID3v2::Tag *id3v2 = mpegFile.ID3v2Tag();
00051     if (id3v2 != 0) {
00052         ID3v2::FrameListMap map = id3v2->frameListMap();
00053         ID3v2::FrameList fl = map["TXXX"];
00054         if (!fl.isEmpty()) {
00055             QString v = toQString(fl.front()->toString());
00056             if (v.contains(fmpsRx)) {
00057                 QString ratingStr = fmpsRx.cap(1);
00058                 double dr = ratingStr.toDouble() * 10.0;
00059                 int rating = (int)dr;
00060                 Preference p(rating);
00061                 retval.setPreference(p);
00062             }
00063         }
00064         //ID3v2::FrameList::ConstIterator litr = fl.begin();
00065 //        while (litr != fl.end()) {
00066 //            ++litr;
00067 //        }
00068     }
00069 #else
00070     // musicmatch style preference
00071     retval.setPreference(retval.comment());
00072 #endif
00073 
00074 //start id="functor"
00075     QTime time(0,0,0,0);
00076     const AudioProperties* ap = f.audioProperties();
00077     time = time.addSecs(ap->length());
00078     retval.setTrackTime(time);
00079     return retval;
00080 }
00081 //end
00082 
00083 const QStringList & TagLib::MetaDataLoader::supportedExtensions() {
00084     static QStringList sl;
00085     // TODO: get from Phonon backend mimetypes list?
00086     if (sl.isEmpty())
00087         sl << "*.mp3" << "*.flac" << "*.wma" << "*.ogg" << "*.aiff";
00088     return sl;
00089 }
00090 
00091 TagLib::MetaDataLoader* TagLib::MetaDataLoader::instance() {
00092     static TagLib::MetaDataLoader* inst = 0;
00093     if (inst == 0) {
00094         inst = new TagLib::MetaDataLoader(qApp);
00095     }
00096     return inst;
00097 }
00098 
00099 //start id="metadataloader"
00100 TagLib::MetaDataLoader::MetaDataLoader(QObject *parent) :
00101     SUPER(parent) {
00102     m_processingMax = 0;
00103     m_running = false;
00104     qDebug() << "TagLib::MetaDataLoader created.";
00105     connect (this, SIGNAL(finished()), this, SLOT(checkForWork()),
00106              Qt::QueuedConnection);
00107 }
00108 
00109 void TagLib::MetaDataLoader::get(QString path) {
00110     m_queue << path;
00111     m_timer.singleShot(2000, this, SLOT(checkForWork()));
00112 }
00113 
00114 void TagLib::MetaDataLoader::checkForWork() {
00115     MetaDataFunctor functor;
00116     if (m_queue.isEmpty() && !m_running) {
00117         m_processingMax = 0;
00118         return;
00119     }
00120     if (m_running ) return;
00121     m_running = true;
00122     m_canceled = false;
00123     while (!m_queue.isEmpty()) {
00124         QStringList sl = m_queue;
00125         m_queue = QStringList();
00126         m_processingMax = sl.length();
00127         emit progressRangeChanged(0, m_processingMax);
00128         for (int i=0; i<m_processingMax;++i) {
00129             if (m_canceled) break;
00130             emit fetched(functor(sl[i]));
00131             emit progressValueChanged(i);
00132             qApp->processEvents();          /* Allow the GUI to process events
00133                 (and our signals to be delivered). */
00134         }
00135         m_running = false;
00136     }
00137     emit finished();
00138 }
00139 //end
00140 
00141 void TagLib::MetaDataLoader::cancel() {
00142     m_canceled = true;
00143 }
00144 
00145 void TagLib::MetaDataLoader::get(QStringList paths) {
00146     m_queue.append(paths);
00147     checkForWork();
00148 }
00149 
00150 MetaDataLoader* MetaDataLoader::clone(QObject *parent) {
00151     return new MetaDataLoader(parent);
00152 }
00153 
 All Classes Namespaces Functions Enumerations