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 \
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
<valuemap type="QVariantMap">
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Maemo</value>
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.MaemoDeviceTarget</value>
- <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">1</value>
+ <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">0</value>
<value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
<valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
<valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.0" type="QVariantMap">
<valuemap key="Qt4ProjectManager.MaemoRunConfiguration.DebuggingHelpersLastDeployed" type="QVariantMap"/>
<value key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId" type="qulonglong">1</value>
<valuemap key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployed" type="QVariantMap">
- <value key="192.168.77.2" type="QDateTime">2010-09-05T03:10:24</value>
+ <value key="192.168.77.2" type="QDateTime">2010-09-05T16:54:31</value>
</valuemap>
</valuemap>
<value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
//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);
using namespace SomePlayer::DataObjects;
using namespace SomePlayer::Storage;
-Library::Library(QString databasePath, QString playlistsPath) {
+#include "mediascanner.h"
+#include <QDir>
+#include <QDebug>
+
+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() {
}
void Library::addDirectory(QString path) {
- /// TODO: implement this
+ _scanner->init(path);
+ _scanner->start(QThread::LowestPriority);
}
void Library::addFile(QString path) {
_library_storage->removeTrack(track);
}
+void Library::addTrack(Track track) {
+ _library_storage->addTrack(track);
+}
+
void Library::addToFavorites(Track track) {
_library_storage->addToFavorites(track);
}
#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
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();
Playlist getNeverPlayed();
Playlist getRecentlyAdded();
- void removeTrack(Track);
- void addTrack(Track);
- void addToFavorites(Track);
-
- void updateTrack(Track);
-
QList<Playlist> getPlaylists();
void savePlaylist(Playlist playlist);
void removePlaylist(Playlist playlist);
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);
};
};
a.setApplicationName("someplayer");
MainWindow w;
+
#if defined(Q_WS_S60)
w.showMaximized();
#else
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
-#include "player.h"
+#include <QFile>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
{
ui->setupUi(this);
connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openMedia()));
- player = new Player();
}
MainWindow::~MainWindow()
void MainWindow::openMedia()
{
- QString filename = QFileDialog::getOpenFileName(this, "Open media", "/home/user/");
- player->playSong(filename);
-
}
#define MAINWINDOW_H
#include <QMainWindow>
-#include "player.h"
namespace Ui {
class MainWindow;
private:
Ui::MainWindow *ui;
- Player *player;
public slots:
void openMedia();
--- /dev/null
+#include "mediascanner.h"
+
+using namespace SomePlayer::Storage;
+
+#include <QMap>
+
+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);
+}
--- /dev/null
+#ifndef MEDIASCANNER_H
+#define MEDIASCANNER_H
+
+#include "someplayer.h"
+#include "track.h"
+#include <QThread>
+#include <QDir>
+#include <QDirIterator>
+
+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
// common includes
#include <QString>
+#include <QStringList>
#include <QList>
#include <QMap>
#include <QUrl>
--- /dev/null
+#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<QString, QString> 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);
+ }
+ }
+ }
+}
--- /dev/null
+#ifndef TAGRESOLVER_H
+#define TAGRESOLVER_H
+
+#include <QObject>
+#include "someplayer.h"
+#include "track.h"
+#include <phonon/MediaObject>
+#include <phonon/MediaSource>
+
+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<Phonon::MediaSource> _sources;
+
+};
+
+#endif // TAGRESOLVER_H
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) {