metadataloader.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include <QDebug>
  2. #include <QApplication>
  3. #include <QMediaPlayer>
  4. #include "metadataloader.h"
  5. using namespace Mobility;
  6. MetaDataLoader::MetaDataLoader(QObject* parent) :
  7. Abstract::MetaDataLoader(parent) {
  8. setObjectName("MetaDataLoader");
  9. m_player = new QMediaPlayer(this);
  10. m_fetched = false;
  11. m_isRunning = false;
  12. m_timeOut.setSingleShot(true);
  13. connect (m_player, SIGNAL(metaDataChanged()), this, SLOT(fetch()));
  14. connect (&m_timeOut, SIGNAL(timeout()), this, SLOT(timeOutSlot()));
  15. }
  16. MetaDataLoader* MetaDataLoader::clone(QObject *parent) {
  17. return new MetaDataLoader(parent);
  18. }
  19. MetaDataLoader* MetaDataLoader::instance() {
  20. static MetaDataLoader* retval = 0;
  21. if (retval == 0) {
  22. qDebug() << "Mobility::MetaDataLoader";
  23. retval = new MetaDataLoader(qApp);
  24. }
  25. return retval;
  26. }
  27. void MetaDataLoader::get(QUrl url) {
  28. m_queue << url;
  29. if (!m_isRunning) {
  30. m_timer.singleShot(20, this, SLOT(checkForWork()));
  31. }
  32. else {
  33. m_timer.singleShot(2000, this, SLOT(checkForWork()));
  34. }
  35. }
  36. void MetaDataLoader::fetch() {
  37. static int numFields = 0;
  38. static int oldNumFields = 0;
  39. numFields = m_player->availableMetaData().count() + m_player->availableExtendedMetaData().count();
  40. // qDebug() << "NumFields: " << numFields;
  41. // qDebug() << "extended: " << m_player->availableExtendedMetaData().join(",");
  42. if (m_fetched) return;
  43. if (m_player->error() != QMediaPlayer::NoError) {
  44. qDebug() << "fetch error: " << m_player->errorString() << m_player->error();
  45. failed();
  46. }
  47. if (!m_player->metaData(QtMultimediaKit::AlbumArtist).isNull())
  48. m_current.setArtist(m_player->metaData(QtMultimediaKit::AlbumArtist).toString());
  49. if (!m_player->metaData(QtMultimediaKit::AlbumTitle).isNull())
  50. m_current.setAlbumTitle(m_player->metaData(QtMultimediaKit::AlbumTitle).toString());
  51. if (!m_player->metaData(QtMultimediaKit::TrackNumber).isNull())
  52. m_current.setTrackNumber(m_player->metaData(QtMultimediaKit::TrackNumber).toString());
  53. if (!m_player->metaData(QtMultimediaKit::Comment).isNull())
  54. m_current.setComment(m_player->metaData(QtMultimediaKit::Comment).toString());
  55. if (!m_player->metaData(QtMultimediaKit::Title).isNull())
  56. m_current.setTrackTitle(m_player->metaData(QtMultimediaKit::Title).toString());
  57. if (!m_player->metaData(QtMultimediaKit::Genre).isNull())
  58. m_current.setGenre(m_player->metaData(QtMultimediaKit::Genre).toString());
  59. // QVariant imgvar = m_player->metaData(QtMultimediaKit::CoverArtImage);
  60. // QList<QtMultimediaKit::MetaData> metadata = m_player->availableMetaData ();
  61. // QStringList sl = m_player->availableExtendedMetaData();
  62. /* if (!imgvar.isNull())
  63. m_current.setImage(qVariantValue<QImage>(imgvar)); */
  64. if (m_player->duration() > 0) {
  65. QTime t;
  66. t = t.addMSecs(m_player->duration());
  67. m_current.setTrackTime(t);
  68. timeOutSlot();
  69. }
  70. }
  71. void MetaDataLoader::checkForWork() {
  72. if (m_isRunning || m_queue.isEmpty()) return;
  73. m_isRunning = true;
  74. QUrl url = m_queue.first();
  75. m_queue.pop_front();
  76. m_current = MetaDataValue();
  77. m_current.setUrl(url);
  78. // qDebug() << " Fetching: " << url.toString();
  79. QMediaContent mc(url);
  80. m_fetched = false;
  81. m_player->setMedia(mc);
  82. if (m_player->error() == QMediaPlayer::ServiceMissingError ||m_player->error() == QMediaPlayer::ResourceError ) {
  83. // qDebug() << "media player error: " << m_player->errorString() << m_player->error();
  84. m_player->deleteLater();
  85. qDebug() << "MetaDataLoader starting new Media Player.";
  86. m_player = new QMediaPlayer(this);
  87. connect (m_player, SIGNAL(metaDataChanged()), this, SLOT(fetch()));
  88. m_player->setMedia(mc);
  89. }
  90. if (m_player->error() != QMediaPlayer::NoError) {
  91. qDebug() << "2nd media player error (fatal): " << m_player->errorString() << m_player->error();
  92. failed();
  93. return;
  94. }
  95. m_timeOut.singleShot(3000, this, SLOT(timeOutSlot()));
  96. // qDebug() << "checkExited";
  97. }
  98. void MetaDataLoader::cancel() {
  99. m_cancelled = true;
  100. m_queue.clear();
  101. }
  102. void MetaDataLoader::get(QList<QUrl> fns) {
  103. m_queue << fns;
  104. checkForWork();
  105. }
  106. const QStringList& MetaDataLoader::supportedExtensions() {
  107. // TODO: get from QMediaServiceProvider::supportedMimeTypes ()
  108. static QStringList sl;
  109. if (sl.isEmpty()) {
  110. sl << "*.mp3" << "*.flac" << "*.wma" << "*.ogg" << "*.aiff";
  111. }
  112. return sl;
  113. }
  114. void MetaDataLoader::timeOutSlot() {
  115. if (m_fetched) return;
  116. m_timeOut.stop();
  117. m_isRunning = false;
  118. m_fetched = true;
  119. m_player->stop();
  120. emit fetched(m_current);
  121. // Give a short delay so we don't thrash the player
  122. m_timer.singleShot(400, this, SLOT(checkForWork()));
  123. }
  124. void MetaDataLoader::failed() {
  125. if (!m_isRunning) return;
  126. m_isRunning = false;
  127. qDebug() << "Failed to fetch: " << m_current.url();
  128. m_timer.singleShot(400, this, SLOT(checkForWork()));
  129. }
  130. bool MetaDataLoader::isRunning() const {
  131. return m_isRunning;
  132. }