From f67083c92e20ba370dfc518e73b2d8e3b531c9ea Mon Sep 17 00:00:00 2001 From: Andreas Date: Thu, 18 Jul 2013 11:28:53 +0200 Subject: [PATCH] Network remote: Each song will be send after client confirms that the previous track was received. Saves a lot of memory especially when sendings lossless files. --- .../remotecontrolmessages.proto | 1 + src/networkremote/incomingdataparser.cpp | 3 ++ src/networkremote/incomingdataparser.h | 1 + src/networkremote/networkremote.cpp | 4 ++ src/networkremote/outgoingdatacreator.cpp | 40 +++++++++++++++++-- src/networkremote/outgoingdatacreator.h | 10 +++++ 6 files changed, 56 insertions(+), 3 deletions(-) diff --git a/ext/libclementine-remote/remotecontrolmessages.proto b/ext/libclementine-remote/remotecontrolmessages.proto index 4ef943f01..faee383cd 100644 --- a/ext/libclementine-remote/remotecontrolmessages.proto +++ b/ext/libclementine-remote/remotecontrolmessages.proto @@ -16,6 +16,7 @@ enum MsgType { CLOSE_PLAYLIST = 11; GET_LYRICS = 14; DOWNLOAD_SONGS = 15; + SEND_NEXT_SONG = 16; // Lastfm LOVE = 12; BAN = 13; diff --git a/src/networkremote/incomingdataparser.cpp b/src/networkremote/incomingdataparser.cpp index 5e65e6452..2421ae0c6 100644 --- a/src/networkremote/incomingdataparser.cpp +++ b/src/networkremote/incomingdataparser.cpp @@ -149,6 +149,9 @@ void IncomingDataParser::Parse(const pb::remote::Message& msg) { case pb::remote::DOWNLOAD_SONGS: emit SendSongs(msg.request_download_songs(), client); break; + case pb::remote::SEND_NEXT_SONG: + emit SendNextSong(client); + break; default: break; } } diff --git a/src/networkremote/incomingdataparser.h b/src/networkremote/incomingdataparser.h index 3fe5ed962..df7394e7c 100644 --- a/src/networkremote/incomingdataparser.h +++ b/src/networkremote/incomingdataparser.h @@ -45,6 +45,7 @@ signals: void RemoveSongs(const QList& indices); void SeekTo(int seconds); void SendSongs(const pb::remote::RequestDownloadSongs& request, RemoteClient* client); + void SendNextSong(RemoteClient* client); private: Application* app_; diff --git a/src/networkremote/networkremote.cpp b/src/networkremote/networkremote.cpp index 723ad4c49..03442aec8 100644 --- a/src/networkremote/networkremote.cpp +++ b/src/networkremote/networkremote.cpp @@ -163,6 +163,10 @@ void NetworkRemote::AcceptConnection() { SIGNAL(SendSongs(pb::remote::RequestDownloadSongs,RemoteClient*)), outgoing_data_creator_.get(), SLOT(SendSongs(pb::remote::RequestDownloadSongs,RemoteClient*))); + connect(incoming_data_parser_.get(), + SIGNAL(SendNextSong(RemoteClient*)), + outgoing_data_creator_.get(), + SLOT(SendNextSong(RemoteClient*))); } QTcpServer* server = qobject_cast(sender()); diff --git a/src/networkremote/outgoingdatacreator.cpp b/src/networkremote/outgoingdatacreator.cpp index 90e837a2f..aa5f01c8c 100644 --- a/src/networkremote/outgoingdatacreator.cpp +++ b/src/networkremote/outgoingdatacreator.cpp @@ -144,6 +144,8 @@ void OutgoingDataCreator::SendDataToClients(pb::remote::Message* msg) { if (client->isDownloader()) { if (client->State() != QTcpSocket::ConnectedState) { clients_->removeAt(clients_->indexOf(client)); + delete download_queue_.value(client); + download_queue_.remove(client); delete client; } continue; @@ -547,9 +549,20 @@ void OutgoingDataCreator::SendLyrics(int id, const SongInfoFetcher::Result& resu void OutgoingDataCreator::SendSongs(const pb::remote::RequestDownloadSongs &request, RemoteClient* client) { + + if (!download_queue_.contains(client)) { + download_queue_.insert(client, new QQueue()); + } + + DownloadItem item; + switch (request.download_item()) { case pb::remote::CurrentItem: - SendSingleSong(client, current_song_, 1, 1); + item.song = current_song_; + item.song_no = 1; + item.song_count = 1; + download_queue_.value(client)->append(item); + break; case pb::remote::ItemAlbum: SendAlbum(client, current_song_); @@ -560,6 +573,19 @@ void OutgoingDataCreator::SendSongs(const pb::remote::RequestDownloadSongs &requ default: break; } + + // Send first file + SendNextSong(client); +} + +void OutgoingDataCreator::SendNextSong(RemoteClient *client) { + if (!download_queue_.contains(client)) + return; + + // Get the item and send the single song + DownloadItem item; + item = download_queue_.value(client)->dequeue(); + SendSingleSong(client, item.song, item.song_no, item.song_count); } void OutgoingDataCreator::SendSingleSong(RemoteClient* client, const Song &song, @@ -620,7 +646,11 @@ void OutgoingDataCreator::SendAlbum(RemoteClient *client, const Song &song) { SongList album = app_->library_backend()->GetSongsByAlbum(song.album()); foreach (Song s, album) { - SendSingleSong(client, s, album.indexOf(s)+1, album.size()); + DownloadItem item; + item.song = s; + item.song_no = album.indexOf(s)+1; + item.song_count = album.size(); + download_queue_.value(client)->append(item); } } @@ -633,6 +663,10 @@ void OutgoingDataCreator::SendPlaylist(RemoteClient *client, int playlist_id) { SongList song_list = playlist->GetAllSongs(); foreach (Song s, song_list) { - SendSingleSong(client, s, song_list.indexOf(s)+1, song_list.size()); + DownloadItem item; + item.song = s; + item.song_no = song_list.indexOf(s)+1; + item.song_count = song_list.size(); + download_queue_.value(client)->append(item); } } diff --git a/src/networkremote/outgoingdatacreator.h b/src/networkremote/outgoingdatacreator.h index 8b56f2494..bfdbafb46 100644 --- a/src/networkremote/outgoingdatacreator.h +++ b/src/networkremote/outgoingdatacreator.h @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "core/player.h" #include "core/application.h" @@ -26,6 +28,12 @@ typedef QList ProviderList; +struct DownloadItem { + Song song; + int song_no; + int song_count; +}; + class OutgoingDataCreator : public QObject { Q_OBJECT public: @@ -59,6 +67,7 @@ public slots: void GetLyrics(); void SendLyrics(int id, const SongInfoFetcher::Result& result); void SendSongs(const pb::remote::RequestDownloadSongs& request, RemoteClient* client); + void SendNextSong(RemoteClient* client); private: Application* app_; @@ -70,6 +79,7 @@ private: QTimer* keep_alive_timer_; QTimer* track_position_timer_; int keep_alive_timeout_; + QMap* > download_queue_; boost::scoped_ptr ultimate_reader_; ProviderList provider_list_;