From: Nikolay Tischenko Date: Sun, 5 Sep 2010 13:40:48 +0000 (+0700) Subject: Implemented directory scanning and adding tracks to library X-Git-Tag: release-1.0~21 X-Git-Url: http://git.maemo.org/git/?p=someplayer;a=commitdiff_plain;h=7b2a40e92ca217556f2ea5dbb95248b2800909a1 Implemented directory scanning and adding tracks to library --- diff --git a/someplayer.pro b/someplayer.pro index 09682c6..d6ad5bc 100644 --- a/someplayer.pro +++ b/someplayer.pro @@ -19,7 +19,9 @@ SOURCES += src/main.cpp\ src/library.cpp \ src/storage.cpp \ src/filestorage.cpp \ - src/dbstorage.cpp + src/dbstorage.cpp \ + src/mediascanner.cpp \ + src/tagresolver.cpp HEADERS += src/mainwindow.h \ src/player.h \ @@ -30,7 +32,9 @@ HEADERS += src/mainwindow.h \ src/library.h \ src/storage.h \ src/filestorage.h \ - src/dbstorage.h + src/dbstorage.h \ + src/mediascanner.h \ + src/tagresolver.h FORMS += src/ui/mainwindow.ui diff --git a/someplayer.pro.user b/someplayer.pro.user index 5ed6616..4082206 100644 --- a/someplayer.pro.user +++ b/someplayer.pro.user @@ -107,7 +107,7 @@ Maemo Qt4ProjectManager.Target.MaemoDeviceTarget - 1 + 0 0 @@ -202,7 +202,7 @@ 1 - 2010-09-05T03:10:24 + 2010-09-05T16:54:31 1 diff --git a/src/dbstorage.cpp b/src/dbstorage.cpp index 95cc980..7c6af3a 100644 --- a/src/dbstorage.cpp +++ b/src/dbstorage.cpp @@ -270,7 +270,14 @@ void DbStorage::addTrack(Track track) { //big bang return; } - QSqlQuery* query = _insert_track_query; + QSqlQuery *query = _check_track_query; + query->bindValue(":source", source); + query->exec(); + if (query->next()) { + // already in datebase, skip + return; + } + query = _insert_track_query; query->bindValue(":title", title); query->bindValue(":artist_id", artist_id); query->bindValue(":album_id", album_id); diff --git a/src/library.cpp b/src/library.cpp index bfd8a1d..5dcfaf4 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -3,9 +3,17 @@ using namespace SomePlayer::DataObjects; using namespace SomePlayer::Storage; -Library::Library(QString databasePath, QString playlistsPath) { +#include "mediascanner.h" +#include +#include + +Library::Library(QString databasePath, QString playlistsPath) : QObject(0) { _library_storage = new DbStorage(databasePath); _playlist_storage = new FileStorage(playlistsPath); + _scanner = new MediaScanner(); + _resolver = new TagResolver(this); + connect(_scanner, SIGNAL(scanFinish(QStringList)), _resolver, SLOT(decode(QStringList))); + connect(_resolver, SIGNAL(decoded(Track)), this, SLOT(addTrack(Track))); } Library::~Library() { @@ -14,7 +22,8 @@ Library::~Library() { } void Library::addDirectory(QString path) { - /// TODO: implement this + _scanner->init(path); + _scanner->start(QThread::LowestPriority); } void Library::addFile(QString path) { @@ -57,6 +66,10 @@ void Library::removeTrack(Track track) { _library_storage->removeTrack(track); } +void Library::addTrack(Track track) { + _library_storage->addTrack(track); +} + void Library::addToFavorites(Track track) { _library_storage->addToFavorites(track); } diff --git a/src/library.h b/src/library.h index 1a4ecc7..08414c3 100644 --- a/src/library.h +++ b/src/library.h @@ -6,6 +6,8 @@ #include "playlist.h" #include "dbstorage.h" #include "filestorage.h" +#include "mediascanner.h" +#include "tagresolver.h" // represents media library: tracks, playlists // it uses different media storages for tracks and playlists @@ -15,11 +17,13 @@ using SomePlayer::DataObjects::Track; using SomePlayer::DataObjects::Playlist; using SomePlayer::Storage::DbStorage; using SomePlayer::Storage::FileStorage; +using SomePlayer::Storage::MediaScanner; namespace SomePlayer { namespace DataObjects { - class Library { + class Library : public QObject { + Q_OBJECT public: Library(QString databasePath, QString playlistsPath); ~Library(); @@ -36,12 +40,6 @@ namespace SomePlayer { Playlist getNeverPlayed(); Playlist getRecentlyAdded(); - void removeTrack(Track); - void addTrack(Track); - void addToFavorites(Track); - - void updateTrack(Track); - QList getPlaylists(); void savePlaylist(Playlist playlist); void removePlaylist(Playlist playlist); @@ -52,6 +50,14 @@ namespace SomePlayer { private: DbStorage *_library_storage; FileStorage *_playlist_storage; + MediaScanner *_scanner; + TagResolver *_resolver; + + public slots: + void removeTrack(Track); + void addTrack(Track); + void addToFavorites(Track); + void updateTrack(Track); }; }; diff --git a/src/main.cpp b/src/main.cpp index 35ab0cb..b42524a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ int main(int argc, char *argv[]) a.setApplicationName("someplayer"); MainWindow w; + #if defined(Q_WS_S60) w.showMaximized(); #else diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 67141bc..2c576f9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2,7 +2,7 @@ #include "ui_mainwindow.h" #include #include -#include "player.h" +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), @@ -10,7 +10,6 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openMedia())); - player = new Player(); } MainWindow::~MainWindow() @@ -20,7 +19,4 @@ MainWindow::~MainWindow() void MainWindow::openMedia() { - QString filename = QFileDialog::getOpenFileName(this, "Open media", "/home/user/"); - player->playSong(filename); - } diff --git a/src/mainwindow.h b/src/mainwindow.h index 1a9e1f4..6662fb8 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -2,7 +2,6 @@ #define MAINWINDOW_H #include -#include "player.h" namespace Ui { class MainWindow; @@ -18,7 +17,6 @@ public: private: Ui::MainWindow *ui; - Player *player; public slots: void openMedia(); diff --git a/src/mediascanner.cpp b/src/mediascanner.cpp new file mode 100644 index 0000000..000d35c --- /dev/null +++ b/src/mediascanner.cpp @@ -0,0 +1,44 @@ +#include "mediascanner.h" + +using namespace SomePlayer::Storage; + +#include + +MediaScanner::MediaScanner(QObject *parent) : + QThread(parent), _stopped(false), _initialized(false) +{ + REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "acc"; + _iterator = NULL; +} + +void MediaScanner::run() { + if (!_initialized) + return; + _foundMedia.clear(); + while(!_stopped && _iterator->hasNext()) { + QString entry(_iterator->next()); + QFileInfo info(entry); + if (info.isReadable()) { + QString suffix = info.suffix().toLower(); + if (REGISTERED_FILE_EXTENSIONS.contains(suffix)) { + if (!_foundMedia.contains(info.absoluteFilePath())) + _foundMedia << info.absoluteFilePath(); + } + } + } + emit scanFinish(_foundMedia); + _stopped = true; +} + +void MediaScanner::stop() { + _stopped = true; + _initialized = false; +} + +void MediaScanner::init(QString dir) { + _stopped = false; + _initialized = true; + if (!_iterator) + delete _iterator; + _iterator = new QDirIterator(QDir(dir), QDirIterator::Subdirectories); +} diff --git a/src/mediascanner.h b/src/mediascanner.h new file mode 100644 index 0000000..c350f3a --- /dev/null +++ b/src/mediascanner.h @@ -0,0 +1,37 @@ +#ifndef MEDIASCANNER_H +#define MEDIASCANNER_H + +#include "someplayer.h" +#include "track.h" +#include +#include +#include + +namespace SomePlayer { + namespace Storage { + + class MediaScanner : public QThread + { + + Q_OBJECT + public: + explicit MediaScanner(QObject *parent = 0); + void run(); + + signals: + void scanFinish(QStringList); + public slots: + void stop(); + void init(QString); + private: + QDirIterator *_iterator; + bool _stopped; + bool _initialized; + QStringList REGISTERED_FILE_EXTENSIONS; + QStringList _foundMedia; + }; + + }; +}; + +#endif // MEDIASCANNER_H diff --git a/src/someplayer.h b/src/someplayer.h index 5fb43f6..f87ce07 100644 --- a/src/someplayer.h +++ b/src/someplayer.h @@ -13,6 +13,7 @@ namespace SomePlayer { // common includes #include +#include #include #include #include diff --git a/src/tagresolver.cpp b/src/tagresolver.cpp new file mode 100644 index 0000000..8be3b86 --- /dev/null +++ b/src/tagresolver.cpp @@ -0,0 +1,37 @@ +#include "tagresolver.h" + +using namespace SomePlayer::DataObjects; + +TagResolver::TagResolver(QObject *parent) : + QObject(parent) +{ + _metaObject = new Phonon::MediaObject(this); + connect(_metaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(metaStateChanged(Phonon::State,Phonon::State))); +} + +void TagResolver::decode(QStringList files) { + _sources.clear(); + foreach (QString filename, files) { + _sources.append(Phonon::MediaSource(filename)); + } + if (!_sources.isEmpty()) { + _metaObject->setCurrentSource(_sources.at(0)); + } +} + +void TagResolver::metaStateChanged(Phonon::State newState, Phonon::State /*oldState*/) { + if (newState == Phonon::StoppedState) { + Phonon::MediaSource source = _metaObject->currentSource(); + if (source.type() != Phonon::MediaSource::Invalid) { + QMap meta = _metaObject->metaData(); + TrackMetadata metadata(meta.value("TITLE"), meta.value("ARTIST"), meta.value("ALBUM")); + Track track(0, metadata, source.fileName()); + emit decoded(track); + int index = _sources.indexOf(source)+1; + if (index != _sources.size()) { + Phonon::MediaSource newSource = _sources.at(index); + _metaObject->setCurrentSource(newSource); + } + } + } +} diff --git a/src/tagresolver.h b/src/tagresolver.h new file mode 100644 index 0000000..1a0a405 --- /dev/null +++ b/src/tagresolver.h @@ -0,0 +1,32 @@ +#ifndef TAGRESOLVER_H +#define TAGRESOLVER_H + +#include +#include "someplayer.h" +#include "track.h" +#include +#include + +using SomePlayer::DataObjects::Track; + +class TagResolver : public QObject +{ + Q_OBJECT +public: + explicit TagResolver(QObject *parent = 0); +public slots: + void decode (QStringList files); + +signals: + void decoded(Track); + +private slots: + void metaStateChanged(Phonon::State newState, Phonon::State /*oldState*/); +private: + QStringList _files; + Phonon::MediaObject *_metaObject; + QList _sources; + +}; + +#endif // TAGRESOLVER_H diff --git a/src/trackmetainformation.cpp b/src/trackmetainformation.cpp index e88f7ae..0cf35f4 100644 --- a/src/trackmetainformation.cpp +++ b/src/trackmetainformation.cpp @@ -5,10 +5,10 @@ using namespace SomePlayer::DataObjects; TrackMetadata::TrackMetadata() { } -TrackMetadata::TrackMetadata(QString title = "", QString artist = "", QString album = "") { - _metadata["TITLE"] = title; - _metadata["ARTIST"] = artist; - _metadata["ALBUM"] = album; +TrackMetadata::TrackMetadata(QString title = "Unknown title", QString artist = "Unknown artist", QString album = "Unknown album") { + _metadata["TITLE"] = title == "" ? "Unknown title" : title; + _metadata["ARTIST"] = artist == "" ? "Unknown artist" : artist; + _metadata["ALBUM"] = album == "" ? "Unknown album" : album; } TrackMetadata::TrackMetadata(const TrackMetadata &metadata) {