The network remote can now send lyrics to clients.
This commit is contained in:
parent
a650ac91bd
commit
9e0b877e5a
@ -14,6 +14,7 @@ enum MsgType {
|
|||||||
REMOVE_SONGS = 9;
|
REMOVE_SONGS = 9;
|
||||||
OPEN_PLAYLIST = 10;
|
OPEN_PLAYLIST = 10;
|
||||||
CLOSE_PLAYLIST = 11;
|
CLOSE_PLAYLIST = 11;
|
||||||
|
GET_LYRICS = 14;
|
||||||
// Lastfm
|
// Lastfm
|
||||||
LOVE = 12;
|
LOVE = 12;
|
||||||
BAN = 13;
|
BAN = 13;
|
||||||
@ -42,6 +43,7 @@ enum MsgType {
|
|||||||
UPDATE_TRACK_POSITION = 46;
|
UPDATE_TRACK_POSITION = 46;
|
||||||
ACTIVE_PLAYLIST_CHANGED = 47;
|
ACTIVE_PLAYLIST_CHANGED = 47;
|
||||||
FIRST_DATA_SENT_COMPLETE = 48;
|
FIRST_DATA_SENT_COMPLETE = 48;
|
||||||
|
LYRICS = 49;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid Engine states
|
// Valid Engine states
|
||||||
@ -212,9 +214,19 @@ message RequestClosePlaylist {
|
|||||||
optional int32 playlist_id = 1;
|
optional int32 playlist_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Message containing lyrics
|
||||||
|
message ResponseLyrics {
|
||||||
|
repeated Lyric lyrics = 1;
|
||||||
|
}
|
||||||
|
message Lyric {
|
||||||
|
optional string id = 1;
|
||||||
|
optional string title = 2;
|
||||||
|
optional string content = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// The message itself
|
// The message itself
|
||||||
message Message {
|
message Message {
|
||||||
optional int32 version = 1 [default=7];
|
optional int32 version = 1 [default=8];
|
||||||
optional MsgType type = 2 [default=UNKNOWN]; // What data is in the message?
|
optional MsgType type = 2 [default=UNKNOWN]; // What data is in the message?
|
||||||
|
|
||||||
optional RequestConnect request_connect = 21;
|
optional RequestConnect request_connect = 21;
|
||||||
@ -239,4 +251,5 @@ message Message {
|
|||||||
optional ResponseUpdateTrackPosition response_update_track_position = 20;
|
optional ResponseUpdateTrackPosition response_update_track_position = 20;
|
||||||
optional ResponseDisconnect response_disconnect = 22;
|
optional ResponseDisconnect response_disconnect = 22;
|
||||||
optional ResponseActiveChanged response_active_changed = 24;
|
optional ResponseActiveChanged response_active_changed = 24;
|
||||||
|
optional ResponseLyrics response_lyrics = 30;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,8 @@ void IncomingDataParser::Parse(const pb::remote::Message& msg) {
|
|||||||
break;
|
break;
|
||||||
case pb::remote::BAN: emit Ban();
|
case pb::remote::BAN: emit Ban();
|
||||||
break;
|
break;
|
||||||
|
case pb::remote::GET_LYRICS: emit GetLyrics();
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ signals:
|
|||||||
void SendPlaylistSongs(int id);
|
void SendPlaylistSongs(int id);
|
||||||
void Open(int id);
|
void Open(int id);
|
||||||
void Close(int id);
|
void Close(int id);
|
||||||
|
void GetLyrics();
|
||||||
void Love();
|
void Love();
|
||||||
void Ban();
|
void Ban();
|
||||||
|
|
||||||
|
@ -155,6 +155,9 @@ void NetworkRemote::AcceptConnection() {
|
|||||||
SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)),
|
SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)),
|
||||||
outgoing_data_creator_.get(),
|
outgoing_data_creator_.get(),
|
||||||
SLOT(SendShuffleMode(PlaylistSequence::ShuffleMode)));
|
SLOT(SendShuffleMode(PlaylistSequence::ShuffleMode)));
|
||||||
|
|
||||||
|
connect(incoming_data_parser_.get(), SIGNAL(GetLyrics()),
|
||||||
|
outgoing_data_creator_.get(), SLOT(GetLyrics()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QTcpServer* server = qobject_cast<QTcpServer*>(sender());
|
QTcpServer* server = qobject_cast<QTcpServer*>(sender());
|
||||||
|
@ -19,21 +19,23 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QtConcurrentRun>
|
||||||
|
|
||||||
#include "networkremote.h"
|
#include "networkremote.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/timeconstants.h"
|
#include "core/timeconstants.h"
|
||||||
|
|
||||||
OutgoingDataCreator::OutgoingDataCreator(Application* app)
|
OutgoingDataCreator::OutgoingDataCreator(Application* app)
|
||||||
: app_(app)
|
: app_(app),
|
||||||
|
ultimate_reader_(new UltimateLyricsReader(this)),
|
||||||
|
fetcher_(new SongInfoFetcher(this))
|
||||||
{
|
{
|
||||||
// Create Keep Alive Timer
|
// Create Keep Alive Timer
|
||||||
keep_alive_timer_ = new QTimer(this);
|
keep_alive_timer_ = new QTimer(this);
|
||||||
connect(keep_alive_timer_, SIGNAL(timeout()), this, SLOT(SendKeepAlive()));
|
connect(keep_alive_timer_, SIGNAL(timeout()), this, SLOT(SendKeepAlive()));
|
||||||
keep_alive_timeout_ = 10000;
|
keep_alive_timeout_ = 10000;
|
||||||
|
|
||||||
// Create the song position timer
|
|
||||||
track_position_timer_ = new QTimer(this);
|
|
||||||
connect(track_position_timer_, SIGNAL(timeout()), this, SLOT(UpdateTrackPosition()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutgoingDataCreator::~OutgoingDataCreator() {
|
OutgoingDataCreator::~OutgoingDataCreator() {
|
||||||
@ -49,6 +51,22 @@ void OutgoingDataCreator::SetClients(QList<RemoteClient*>* clients) {
|
|||||||
if (app_->player()->engine()->state() == Engine::Playing) {
|
if (app_->player()->engine()->state() == Engine::Playing) {
|
||||||
track_position_timer_->start(1000);
|
track_position_timer_->start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the song position timer
|
||||||
|
track_position_timer_ = new QTimer(this);
|
||||||
|
connect(track_position_timer_, SIGNAL(timeout()), this, SLOT(UpdateTrackPosition()));
|
||||||
|
|
||||||
|
// Parse the ultimate lyrics xml file
|
||||||
|
ultimate_reader_->SetThread(this->thread());
|
||||||
|
provider_list_ = ultimate_reader_->Parse(":lyrics/ultimate_providers.xml");
|
||||||
|
|
||||||
|
// Set up the lyrics parser
|
||||||
|
connect(fetcher_, SIGNAL(ResultReady(int,SongInfoFetcher::Result)),
|
||||||
|
SLOT(SendLyrics(int,SongInfoFetcher::Result)));
|
||||||
|
|
||||||
|
foreach (SongInfoProvider* provider, provider_list_) {
|
||||||
|
fetcher_->AddProvider(provider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutgoingDataCreator::SendDataToClients(pb::remote::Message* msg) {
|
void OutgoingDataCreator::SendDataToClients(pb::remote::Message* msg) {
|
||||||
@ -428,3 +446,29 @@ void OutgoingDataCreator::DisconnectAllClients() {
|
|||||||
msg.mutable_response_disconnect()->set_reason_disconnect(pb::remote::Server_Shutdown);
|
msg.mutable_response_disconnect()->set_reason_disconnect(pb::remote::Server_Shutdown);
|
||||||
SendDataToClients(&msg);
|
SendDataToClients(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutgoingDataCreator::GetLyrics() {
|
||||||
|
fetcher_->FetchInfo(current_song_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutgoingDataCreator::SendLyrics(int id, const SongInfoFetcher::Result& result) {
|
||||||
|
pb::remote::Message msg;
|
||||||
|
msg.set_type(pb::remote::LYRICS);
|
||||||
|
pb::remote::ResponseLyrics* response = msg.mutable_response_lyrics();
|
||||||
|
|
||||||
|
foreach (const CollapsibleInfoPane::Data& data, result.info_) {
|
||||||
|
// If the size is zero, do not send the provider
|
||||||
|
SongInfoTextView* editor = qobject_cast<SongInfoTextView*>(data.contents_);
|
||||||
|
if (editor->toPlainText().length() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pb::remote::Lyric* lyric = response->mutable_lyrics()->Add();
|
||||||
|
|
||||||
|
lyric->set_id(DataCommaSizeFromQString(data.id_));
|
||||||
|
lyric->set_title(DataCommaSizeFromQString(data.title_));
|
||||||
|
lyric->set_content(DataCommaSizeFromQString(editor->toPlainText()));
|
||||||
|
}
|
||||||
|
SendDataToClients(&msg);
|
||||||
|
|
||||||
|
results_.take(id);
|
||||||
|
}
|
||||||
|
@ -13,8 +13,17 @@
|
|||||||
#include "playlist/playlist.h"
|
#include "playlist/playlist.h"
|
||||||
#include "playlist/playlistmanager.h"
|
#include "playlist/playlistmanager.h"
|
||||||
#include "playlist/playlistbackend.h"
|
#include "playlist/playlistbackend.h"
|
||||||
|
#include "songinfo/collapsibleinfopane.h"
|
||||||
|
#include "songinfo/songinfofetcher.h"
|
||||||
|
#include "songinfo/songinfoprovider.h"
|
||||||
|
#include "songinfo/songinfotextview.h"
|
||||||
|
#include "songinfo/ultimatelyricsprovider.h"
|
||||||
|
#include "songinfo/ultimatelyricsreader.h"
|
||||||
#include "remotecontrolmessages.pb.h"
|
#include "remotecontrolmessages.pb.h"
|
||||||
#include "remoteclient.h"
|
#include "remoteclient.h"
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
typedef QList<SongInfoProvider*> ProviderList;
|
||||||
|
|
||||||
class OutgoingDataCreator : public QObject {
|
class OutgoingDataCreator : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -44,6 +53,8 @@ public slots:
|
|||||||
void SendShuffleMode(PlaylistSequence::ShuffleMode mode);
|
void SendShuffleMode(PlaylistSequence::ShuffleMode mode);
|
||||||
void UpdateTrackPosition();
|
void UpdateTrackPosition();
|
||||||
void DisconnectAllClients();
|
void DisconnectAllClients();
|
||||||
|
void GetLyrics();
|
||||||
|
void SendLyrics(int id, const SongInfoFetcher::Result& result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
@ -56,6 +67,11 @@ private:
|
|||||||
QTimer* track_position_timer_;
|
QTimer* track_position_timer_;
|
||||||
int keep_alive_timeout_;
|
int keep_alive_timeout_;
|
||||||
|
|
||||||
|
boost::scoped_ptr<UltimateLyricsReader> ultimate_reader_;
|
||||||
|
ProviderList provider_list_;
|
||||||
|
QMap<int, SongInfoFetcher::Result> results_;
|
||||||
|
SongInfoFetcher* fetcher_;
|
||||||
|
|
||||||
void SendDataToClients(pb::remote::Message* msg);
|
void SendDataToClients(pb::remote::Message* msg);
|
||||||
void SetEngineState(pb::remote::ResponseClementineInfo* msg);
|
void SetEngineState(pb::remote::ResponseClementineInfo* msg);
|
||||||
void CreateSong(
|
void CreateSong(
|
||||||
|
@ -24,10 +24,15 @@
|
|||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
UltimateLyricsReader::UltimateLyricsReader(QObject* parent)
|
UltimateLyricsReader::UltimateLyricsReader(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent),
|
||||||
|
thread_(qApp->thread())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UltimateLyricsReader::SetThread(QThread *thread) {
|
||||||
|
thread_ = thread;
|
||||||
|
}
|
||||||
|
|
||||||
QList<SongInfoProvider*> UltimateLyricsReader::Parse(const QString& filename) const {
|
QList<SongInfoProvider*> UltimateLyricsReader::Parse(const QString& filename) const {
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
@ -48,7 +53,7 @@ QList<SongInfoProvider*> UltimateLyricsReader::ParseDevice(QIODevice* device) co
|
|||||||
if (reader.name() == "provider") {
|
if (reader.name() == "provider") {
|
||||||
SongInfoProvider* provider = ParseProvider(&reader);
|
SongInfoProvider* provider = ParseProvider(&reader);
|
||||||
if (provider) {
|
if (provider) {
|
||||||
provider->moveToThread(qApp->thread());
|
provider->moveToThread(thread_);
|
||||||
ret << provider;
|
ret << provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "ultimatelyricsprovider.h"
|
#include "ultimatelyricsprovider.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
@ -34,10 +35,14 @@ public:
|
|||||||
QList<SongInfoProvider*> Parse(const QString& filename) const;
|
QList<SongInfoProvider*> Parse(const QString& filename) const;
|
||||||
QList<SongInfoProvider*> ParseDevice(QIODevice* device) const;
|
QList<SongInfoProvider*> ParseDevice(QIODevice* device) const;
|
||||||
|
|
||||||
|
void SetThread(QThread* thread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SongInfoProvider* ParseProvider(QXmlStreamReader* reader) const;
|
SongInfoProvider* ParseProvider(QXmlStreamReader* reader) const;
|
||||||
UltimateLyricsProvider::Rule ParseRule(QXmlStreamReader* reader) const;
|
UltimateLyricsProvider::Rule ParseRule(QXmlStreamReader* reader) const;
|
||||||
QString ParseInvalidIndicator(QXmlStreamReader* reader) const;
|
QString ParseInvalidIndicator(QXmlStreamReader* reader) const;
|
||||||
|
|
||||||
|
QThread* thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ULTIMATELYRICSREADER_H
|
#endif // ULTIMATELYRICSREADER_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user