From ff5a910d33b8ed0ee96ec917f9f8dec3506a63b1 Mon Sep 17 00:00:00 2001 From: Andrei Date: Thu, 29 Mar 2018 00:23:53 +0300 Subject: [PATCH] medacontent --- SoundBand/playlistmodel.cpp | 6 +- SoundBand/playlistmodel.h | 2 +- SoundBand/syncengine.cpp | 4 +- SoundBand/syncengine.h | 2 +- sync/mysql.cpp | 100 ++++++++++++++++++++++-------- sync/mysql.h | 38 ++++++++++-- sync/player.cpp | 18 ------ sync/player.h | 7 --- sync/song.cpp | 72 ++++++++++++++++++++++ sync/song.h | 5 ++ sync/sync.cpp | 120 +++++++++++++++++------------------- sync/sync.h | 37 ++++++----- 12 files changed, 268 insertions(+), 143 deletions(-) diff --git a/SoundBand/playlistmodel.cpp b/SoundBand/playlistmodel.cpp index 1cf184c..9e03ba8 100644 --- a/SoundBand/playlistmodel.cpp +++ b/SoundBand/playlistmodel.cpp @@ -94,7 +94,7 @@ QVariant PlayListModel::data(const QModelIndex &index, int role) const bool PlayListModel::select(int id){ - for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ + for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ if(i->id == id){ if((i->isSelected = !i->isSelected)){ @@ -114,7 +114,7 @@ bool PlayListModel::select(int id){ QList PlayListModel::getSelected(){ QList result; - for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ + for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ if(i->isSelected){ result.push_back(i->id); } @@ -124,7 +124,7 @@ QList PlayListModel::getSelected(){ bool PlayListModel::isSelected(int id){ - for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ + for(QList::Iterator i = playList.begin(); i < playList.end(); i++){ if(i->id == id){ return i->isSelected; } diff --git a/SoundBand/playlistmodel.h b/SoundBand/playlistmodel.h index 58b7c41..bc8d143 100644 --- a/SoundBand/playlistmodel.h +++ b/SoundBand/playlistmodel.h @@ -16,7 +16,7 @@ class PlayListModel : public QAbstractListModel private: SyncEngine * syncEngine; - QList playList; + QList playList; QString playListName; int itemCount; diff --git a/SoundBand/syncengine.cpp b/SoundBand/syncengine.cpp index 1b4ef08..6e00c9b 100644 --- a/SoundBand/syncengine.cpp +++ b/SoundBand/syncengine.cpp @@ -140,7 +140,7 @@ int SyncEngine::repeat()const{ } void SyncEngine::setRepeat(int flag){ - sync->setRepeat((syncLib::Repeat)flag); + sync->setRepeat((QMediaPlaylist::PlaybackMode)flag); } bool SyncEngine::setPlayList(const QString& name){ @@ -157,7 +157,7 @@ bool SyncEngine::setPlayList(const QString& name){ } -bool SyncEngine::getPlayList(QList &playList, const QString &name){ +bool SyncEngine::getPlayList(QList &playList, const QString &name){ return sqlApi->updateAvailableSongs(playList, name, true); } diff --git a/SoundBand/syncengine.h b/SoundBand/syncengine.h index a89f69f..7f908ab 100644 --- a/SoundBand/syncengine.h +++ b/SoundBand/syncengine.h @@ -138,7 +138,7 @@ public slots: * @param name - name of selected playList * @return */ - bool getPlayList(QList &playList, const QString& name); + bool getPlayList(QList &playList, const QString& name); /** * @brief lastError - message of last error diff --git a/sync/mysql.cpp b/sync/mysql.cpp index 3972de0..736a709 100644 --- a/sync/mysql.cpp +++ b/sync/mysql.cpp @@ -3,6 +3,7 @@ #include #include "exaptions.h" #include +#include namespace syncLib{ @@ -118,6 +119,59 @@ void MySql::initDB(const QString &database){ } } +bool MySql::find(const QMediaContent &song, SongStorage &response){ + QList songs; + + if(!updateAvailableSongs(songs)){ + return false; + } + + for(SongStorage &i: songs){ + if(i == song){ + response = i; + return true; + } + } + + return false; + +} + +bool MySql::find(const QMediaContent &song, SongHeader &response){ + QList songs; + + if(!updateAvailableSongs(songs)){ + return false; + } + + for(SongStorage &i: songs){ + if(i == song){ + response = (SongHeader&)i; + return true; + } + } + + return false; + +} + +bool MySql::find(const SongHeader &song, QMediaContent &response){ + QList songs; + + if(!updateAvailableSongs(songs)){ + return false; + } + + for(SongStorage &i: songs){ + if((SongHeader&)i == song){ + response = i.toMedia(); + return true; + } + } + + return false; +} + void MySql::setSoundDir(const QString &str){ songDir = str; QSettings().setValue(MAIN_FOLDER_KEY, songDir); @@ -149,7 +203,7 @@ void MySql::sqlErrorLog(const QString &qyery)const{ #endif } -int MySql::save(const Song &song){ +int MySql::save(const Song &song , bool onlyDataBase){ QString qyer = QString("SELECT id from songs where name='%0' and size=%1").arg(song.name, QString::number(song.size)); if(!qyery->exec(qyer)){ @@ -162,7 +216,7 @@ int MySql::save(const Song &song){ } QUrl url; - if(!saveToStorage(url, song)){ + if(!onlyDataBase && !saveToStorage(url, song)){ return false; } @@ -186,29 +240,19 @@ int MySql::save(const Song &song){ return result; } -int MySql::save(const QString &url){ - QFile f(QUrl(url).toLocalFile()); - if(!f.open(QIODevice::ReadOnly)){ - return -1; - } - QByteArray bytes = f.readAll(); - f.close(); - QString name = url.right(url.lastIndexOf(QRegularExpression("[\\\/]"))); - Song song; - song.name = name; - song.size = bytes.size(); - song.source = bytes; +int MySql::save(const QString &url){ + + SongStorage song(QUrl::fromLocalFile(url)); if(!song.isNameValid()){ return -1; } - return save(song); + return save(song, true); } -bool MySql::load(const SongHeader &song,Song &result){ - result.clear(); +bool MySql::load(const SongHeader &song, SongStorage &result){ if(song.id > -1){ QString qyer = QString("SELECT * from songs where id=%0").arg(song.id); if(!qyery->exec(qyer)){ @@ -230,17 +274,17 @@ bool MySql::load(const SongHeader &song,Song &result){ result.id = qyery->value(0).toInt(); result.name = qyery->value(1).toString(); result.size = qyery->value(2).toInt(); - result.source = qyery->value(3).toByteArray(); + result.url = qyery->value(3).toUrl(); return true; } -bool MySql::updateAvailableSongs(QList& list, const QString& playList, bool forEditing){ +bool MySql::updateAvailableSongs(QList& list, const QString& playList, bool forEditing){ QString qyer; if(playList.isEmpty() || playList == ALL_SONGS_LIST || forEditing){ - qyer = QString("SELECT id,name,size from songs"); + qyer = QString("SELECT * from songs"); }else{ - qyer = QString("SELECT id,name,size from songs where " + qyer = QString("SELECT * from songs where " "id in (select song from playlistsdata where " "playlist='%0')").arg(playList); } @@ -253,11 +297,13 @@ bool MySql::updateAvailableSongs(QList& list, const QString& playLis list.clear(); while(qyery->next()){ - SongHeader song; + SongStorage song; song.isSelected = !forEditing || playList == ALL_SONGS_LIST; song.id = qyery->value(0).toInt(); song.name = qyery->value(1).toString(); song.size = qyery->value(2).toInt(); + song.url = qyery->value(3).toUrl(); + list.push_back(song); } @@ -272,7 +318,7 @@ bool MySql::updateAvailableSongs(QList& list, const QString& playLis } while(qyery->next()){ - for(SongHeader& item:list){ + for(SongStorage& item:list){ int id = qyery->value(0).toInt(); if(item.id == id){ item.isSelected = true; @@ -286,15 +332,15 @@ bool MySql::updateAvailableSongs(QList& list, const QString& playLis return true; } -bool MySql::updateAvailableSongs(QStringList& list, const QString& playList){ +bool MySql::updateAvailableSongs(QMediaPlaylist& list, const QString& playList){ - QList tempList; + QList tempList; if(!updateAvailableSongs(tempList, playList)) return false; - for(SongHeader &header : tempList){ - list.push_back(header.name); + for(SongStorage &header : tempList){ + list.addMedia(header.toMedia()); } return true; diff --git a/sync/mysql.h b/sync/mysql.h index bd85046..a922826 100644 --- a/sync/mysql.h +++ b/sync/mysql.h @@ -37,26 +37,56 @@ public: */ void initDB(const QString& database = DATABASE_NAME ); + /** + * @brief find - find song + * @param song - song header + * @param response Media Content of finded song + * @return true if song finded + */ + bool find(const SongHeader& song, QMediaContent& response); + + /** + * @brief find - find song + * @param song - song header + * @param response Media Content of finded song + * @return true if song finded + */ + bool find(const QMediaContent& song, SongHeader& response); + + /** + * @brief find - find song + * @param song - media Content + * @param response header of finded song + * @return true if song finded + */ + bool find(const QMediaContent& song, SongStorage &response); + /** * @brief setSoundDir * @param str */ void setSoundDir(const QString& str); + /** + * @brief findSong + * @param song + */ + bool findSong(const SongHeader &song); + /** * @brief load song of database; * @brief song - * @brief result - the resulting value; * @return true if everything's done */ - bool load(const SongHeader &song, Song &result); + bool load(const SongHeader &song, SongStorage &result); /** * @brief save media data into local database. * @param song savining media data. * @return id of song saved on local database. */ - int save(const Song &song); + int save(const Song &song, bool onlyDataBase = false); /** * @brief save media file, bud from url. @@ -77,7 +107,7 @@ public: * @param forEdit - flag for editing play list. If this flag = true then return all available songs with corect flag 'isSelect' * @return true if all done */ - bool updateAvailableSongs(QList& list, const QString &playList = "", bool forEditing = false); + bool updateAvailableSongs(QList& list, const QString &playList = "", bool forEditing = false); /** * @brief updateAvelableSongs will update the list of participants of songs. @@ -85,7 +115,7 @@ public: * @param playList - play list of songs (string). * @return true if all done */ - bool updateAvailableSongs(QStringList& list, const QString &playList = ""); + bool updateAvailableSongs(QMediaPlaylist &list, const QString &playList = ""); /** * @brief removeSong - remove song from local database. diff --git a/sync/player.cpp b/sync/player.cpp index 1f8494a..05fa849 100644 --- a/sync/player.cpp +++ b/sync/player.cpp @@ -12,24 +12,6 @@ Player::Player(const QString &bufferFile, QObject *parent, Flags flags): bufferVolume = 0; } -bool Player::setMediaFromBytes(const QByteArray &array){ - QFile f(buffer); - if(!f.open(QIODevice::WriteOnly | QIODevice::Truncate)){ - return false; - } - - if(array.length() != f.write(array.data(),array.length())){ - - f.close(); - return false; - } - f.close(); - - setMedia(QUrl::fromLocalFile(QDir("./").absoluteFilePath(buffer))); - - return true; -} - void Player::syncBegin(){ bufferVolume = volume(); diff --git a/sync/player.h b/sync/player.h index 9af3603..d5077c5 100644 --- a/sync/player.h +++ b/sync/player.h @@ -21,13 +21,6 @@ public: Player(const QString& bufferFile, QObject *parent = Q_NULLPTR, Flags flags = Flags()); - /** - * @brief setMediaFromBytes - * @param array of song data - * @return true if all done - */ - bool setMediaFromBytes(const QByteArray& array); - /** * @brief syncBegin - palyer waiting for sunced. */ diff --git a/sync/song.cpp b/sync/song.cpp index 4911503..2b21672 100644 --- a/sync/song.cpp +++ b/sync/song.cpp @@ -1,6 +1,7 @@ #include "song.h" #include #include +#include namespace syncLib{ @@ -82,6 +83,77 @@ QDataStream& operator >> (QDataStream& stream, SongHeader& song){ } +SongStorage::SongStorage(): + SongHeader() +{ + url.clear(); +} + +SongStorage::SongStorage(const SongHeader& from) + :SongStorage::SongStorage() +{ + this->id = from.id; + this->name = from.name; + this->size = from.size; +} + +SongStorage::SongStorage(const QUrl& from) + :SongStorage::SongStorage() +{ + if(!from.isValid() || !from.isLocalFile()){ + return; + } + + this->id = -1; + if(!getName(name, from)){ + name.clear(); + } + + this->size = QFile(from.toLocalFile()).size(); +} + +const QUrl& SongStorage::getSource()const{ + return url; +} + +bool SongStorage::isValid() const{ + return SongHeader::isValid() && url.isValid(); +} + +SongStorage::~SongStorage(){ + url.clear(); +} + +QMediaContent SongStorage::toMedia()const{ + return QMediaContent(url); +} + +bool SongStorage::toSong(Song&)const{ + Song song(*((SongHeader*)this)); + + QFile f(url.toLocalFile()); + + if(!f.open(QIODevice::ReadOnly)) + return false; + song.source = f.readAll(); + + f.close(); + return song.isValid(); +} + +QDataStream& operator << (QDataStream& stream,const SongStorage& song){ + stream << static_cast(song); + stream << song.url; + return stream; +} + +QDataStream& operator >> (QDataStream& stream, SongStorage& song){ + stream >> static_cast(song); + stream >> song.url; + return stream; +} + + Song::Song(): SongHeader() { diff --git a/sync/song.h b/sync/song.h index bd4acb8..b4affae 100644 --- a/sync/song.h +++ b/sync/song.h @@ -63,7 +63,10 @@ private: public: SongStorage(); SongStorage(const SongHeader& from); + SongStorage(const QUrl& url); + const QUrl& getSource()const; + bool toSong(Song &)const; QMediaContent toMedia()const; bool isValid() const; ~SongStorage(); @@ -89,6 +92,8 @@ public: friend QDataStream& operator << (QDataStream& stream, const Song& song); friend QDataStream& operator >> (QDataStream& stream, Song& song); friend class MySql; + friend class SongStorage; + }; } #endif // SONG_H diff --git a/sync/sync.cpp b/sync/sync.cpp index 91df405..74dd4a1 100644 --- a/sync/sync.cpp +++ b/sync/sync.cpp @@ -23,6 +23,8 @@ Sync::Sync(const QString &address, int port, const QString &datadir): throw MediaException(); } + playList = player->playlist(); + fbroadcaster = false; resyncCount = 0; lastSyncTime = 0; @@ -41,7 +43,7 @@ MySql* Sync::getSqlApi(){ return sql; } -bool Sync::updateSongs(QList& list, const QString& playList){ +bool Sync::updateSongs(QMediaPlaylist& list, const QString& playList){ if(!sql->updateAvailableSongs(list, playList)){ return false; } @@ -59,28 +61,37 @@ const QString& Sync::getPlayListName() const{ return lastUsedPlayList; } -bool Sync::findHeader(const Song &song){ +bool Sync::play(bool fbroadcast){ + fbroadcaster = fbroadcast; - for(int i = 0; i < playList.size(); i++){ - if(playList[i] == static_cast(song)){ - currentSongIndex = i; - return true; - } + if(fbroadcaster){ + player->play(); + sync(); + }else{ + player->syncBegin(); } + emit currentSongChanged(); - return false; + return true; } bool Sync::play(const SongHeader &header, bool fbroadcast){ - Song song; + if(!header.isValid()){ + return false; + } + + SongStorage song; SongHeader newheader = header; newheader.id = -1; if(!sql->load(newheader, song)){ return false; } - return Sync::play(song, fbroadcast); + playList->clear(); + playList->addMedia(song.toMedia()); + + return play(fbroadcast); } bool Sync::play(const Song &song, bool fbroadcast){ @@ -89,27 +100,26 @@ bool Sync::play(const Song &song, bool fbroadcast){ return false; } - if(!player->setMediaFromBytes(song.getSource())){ - return false; - } - - fbroadcaster = fbroadcast; - - if(!findHeader(song) && sql->save(song) > -1 && - updateSongs(playList) && !findHeader(song)){ + QMediaContent savedSong; + if(!sql->find(static_cast(song), savedSong) && sql->save(song) > -1 && + !sql->find((SongHeader&)song, savedSong)){ return false; } - if(fbroadcaster){ - player->play(); - sync(); - }else{ - player->syncBegin(); + return play(savedSong, fbroadcast); +} + +bool Sync::play(const QMediaContent& media, bool fbroadcast){ + + if(media.isNull()){ + return false; } - emit currentSongChanged(); - return true; + playList->clear(); + playList->addMedia(media); + + return Sync::play(fbroadcast); } bool Sync::play(int id_song, bool fbroadcast){ @@ -120,7 +130,7 @@ bool Sync::play(int id_song, bool fbroadcast){ SongHeader header; header.id = id_song; - Song song; + SongStorage song; sql->load(header, song); return Sync::play(song, fbroadcast); @@ -135,22 +145,22 @@ bool Sync::play(QString url){ return Sync::play(id); } -Repeat Sync::repeat()const{ - return _repeat; +QMediaPlaylist::PlaybackMode Sync::repeat()const{ + return playList->playbackMode(); } -void Sync::setRepeat(Repeat flag){ - _repeat = flag; +void Sync::setRepeat(QMediaPlaylist::PlaybackMode flag){ + playList->setPlaybackMode(flag); } bool Sync::pause(bool state){ if(!fbroadcaster){ - if(playList.isEmpty()) + if(playList->isEmpty()) return false; - return play(playList[0]); + return play(); } if(state){ @@ -252,18 +262,21 @@ bool Sync::createPackage(Type type, package &pac){ } if(type & TypePackage::t_song_h && fbroadcaster){ - if(currentSongIndex < 0) + if(playList->currentIndex() < 0) return false; - pac.header = playList[currentSongIndex]; + if(!sql->find(playList->currentMedia(), pac.header)){ + return false; + } } if(type & TypePackage::t_song && fbroadcaster){ - if(currentSongIndex < 0) + if(playList->currentIndex() < 0) return false; - if(!sql->load(playList[currentSongIndex], pac.source)) + SongStorage song; + if(!sql->load(playList->currentMedia(), song) && !song.toSong(pac.source)) return false; } @@ -387,7 +400,7 @@ void Sync::packageRender(ETcpSocket *socket){ // if requst from client if(pkg.getType() & t_play & t_sync){ - if(currentSongIndex < 0){ + if(playList->currentIndex() < 0){ throw SyncError(); socket->nextItem(); continue; @@ -443,27 +456,9 @@ void Sync::deepScaned(QList * list){ } void Sync::endPlay(QMediaPlayer::State state){ - if(state == QMediaPlayer::StoppedState){ - - switch (_repeat) { - case allPlayListRandom: - next(true); - break; - - case allPlayList: - next(false); - break; - - case oneMusic: - play(playList[currentSongIndex]); - break; - - default: - currentSongIndex = -1; + if(state == QMediaPlayer::StoppedState && playList->currentIndex() != -1){ fbroadcaster = false; break; - } - } } @@ -488,19 +483,16 @@ unsigned int Sync::seek() const{ return player->position(); } -const QList* Sync::getPlayList() const{ - return &playList; +const QMediaPlaylist* Sync::getPlayList() const{ + return playList; } int Sync::getCurrentSongIndex()const{ - return currentSongIndex; + return playList->currentIndex(); } -const SongHeader* Sync::getCurrentSong() const{ - if(currentSongIndex < 0 || currentSongIndex >= playList.size()){ - return nullptr; - } - return &playList[currentSongIndex]; +const QMediaContent* Sync::getCurrentSong() const{ + return &playList->currentMedia(); } qint64 Sync::getEndPoint() const { diff --git a/sync/sync.h b/sync/sync.h index a3acf93..e3e3670 100644 --- a/sync/sync.h +++ b/sync/sync.h @@ -15,8 +15,6 @@ typedef std::chrono::time_point Clock; class Node; -enum Repeat{noRepeat, oneMusic, allPlayList, allPlayListRandom}; - /** * @brief The Sync class is main class of this library. @@ -28,9 +26,8 @@ class Sync : public QObject private: Node *node; Player *player; - QMediaPlaylist playList; + QMediaPlaylist *playList; QString lastUsedPlayList; - int currentSongIndex; QList servers; bool fbroadcaster; int resyncCount; @@ -39,13 +36,6 @@ private: LocalScanner deepScaner; MySql *sql; int port; - Repeat _repeat; - - /** - * @brief findHeader set current song if playList have playng song - * @return true if all done - */ - bool findHeader(const Song& song); /** * @brief rescan - search for existing servers @@ -67,7 +57,7 @@ private slots: * @brief updateSongs use method update avelable songs from sql database * @return true if all done */ - bool updateSongs(QList &list, const QString &playList = ""); + bool updateSongs(QMediaPlaylist &list, const QString &playList = ""); /** * @brief packageRender - the handler of all messages received. @@ -97,13 +87,13 @@ public: * @brief repeat * @return flag of repeat */ - Repeat repeat()const; + QMediaPlaylist::PlaybackMode repeat()const; /** * @brief setRepeat * @param flag new flag of repeat */ - void setRepeat(Repeat flag); + void setRepeat(QMediaPlaylist::PlaybackMode flag); /** * @brief getSqlApi @@ -111,6 +101,21 @@ public: */ MySql* getSqlApi(); + /** + * @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption. + * @param fbroadcast - server broadcasting sound. + * @return true if all done else false. + */ + bool play(bool fbroadcast = true); + + /** + * @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption. + * @param header of song + * @param fbroadcast - server broadcasting sound. + * @return true if all done else false. + */ + bool play(const QMediaContent &media, bool fbroadcast = true); + /** * @brief Play song in this device, if device has not supported playning media data this method throw MediaExcrption. * @param header of song @@ -229,7 +234,7 @@ public: * @brief getPlayList * @return list of available songs */ - const QList *getPlayList() const; + const QMediaPlaylist *getPlayList() const; /** * @brief SongHeader::getCurrentSongIndex @@ -241,7 +246,7 @@ public: * @brief getCurrentSong * @return playing song. */ - const SongHeader *getCurrentSong() const; + const QMediaContent *getCurrentSong() const; /** * @brief getEndPoint