oopapidocs
2.0
|
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