diff --git a/client/controller.cpp b/client/controller.cpp index 0cb93603..0802f484 100644 --- a/client/controller.cpp +++ b/client/controller.cpp @@ -23,7 +23,6 @@ #include "decoder/oggDecoder.h" #include "decoder/pcmDecoder.h" #include "decoder/flacDecoder.h" -#include "alsaPlayer.h" #include "timeProvider.h" #include "common/log.h" #include "common/snapException.h" @@ -32,11 +31,12 @@ #include "message/request.h" #include "message/ack.h" #include "message/command.h" +#include "message/hello.h" using namespace std; -Controller::Controller() : MessageReceiver(), active_(false), sampleFormat_(NULL), decoder_(NULL), asyncException_(false) +Controller::Controller() : MessageReceiver(), active_(false), sampleFormat_(NULL), decoder_(NULL), player_(nullptr), asyncException_(false) { } @@ -77,6 +77,18 @@ void Controller::onMessageReceived(ClientConnection* connection, const msg::Base TimeProvider::getInstance().setDiffToServer((reply.latency - latency) * 1000 / 2); // logO << "diff to server [ms]: " << (float)TimeProvider::getInstance().getDiffToServer().count() / 1000.f << "\n"; } + else if (baseMessage.type == message_type::kServerSettings) + { + msg::ServerSettings serverSettings; + serverSettings.deserialize(baseMessage, buffer); + logO << "ServerSettings - buffer: " << serverSettings.bufferMs << ", latency: " << serverSettings.latency << ", volume: " << serverSettings.volume << ", muted: " << serverSettings.muted << "\n"; + if (player_ != nullptr) + { + player_->setVolume(serverSettings.volume / 100.); + player_->setMute(serverSettings.muted); + } + stream_->setBufferLen(serverSettings.bufferMs - serverSettings.latency); + } if (baseMessage.type != message_type::kTime) if (sendTimeSyncMessage(1000)) @@ -167,9 +179,9 @@ void Controller::worker() stream_ = new Stream(*sampleFormat_); stream_->setBufferLen(serverSettings->bufferMs - latency_); - Player player(pcmDevice_, stream_); - player.setVolume(serverSettings->volume); - player.start(); + player_.reset(new Player(pcmDevice_, stream_)); + player_->setVolume(serverSettings->volume); + player_->start(); msg::Command startStream("startStream"); shared_ptr ackMsg(NULL); diff --git a/client/controller.h b/client/controller.h index f8f448b0..d09af828 100644 --- a/client/controller.h +++ b/client/controller.h @@ -26,6 +26,7 @@ #include "clientConnection.h" #include "stream.h" #include "pcmDevice.h" +#include "alsaPlayer.h" /// Forwards PCM data to the audio player @@ -61,6 +62,7 @@ private: Decoder* decoder_; PcmDevice pcmDevice_; size_t latency_; + std::unique_ptr player_; std::exception exception_; bool asyncException_; diff --git a/message/serverSettings.h b/message/serverSettings.h index 66227526..02b30efe 100644 --- a/message/serverSettings.h +++ b/message/serverSettings.h @@ -28,7 +28,7 @@ namespace msg class ServerSettings : public BaseMessage { public: - ServerSettings() : BaseMessage(message_type::kServerSettings), bufferMs(0), latency(0), volume(1.0) + ServerSettings() : BaseMessage(message_type::kServerSettings), bufferMs(0), latency(0), volume(100), muted(false) { } @@ -40,24 +40,27 @@ public: { stream.read(reinterpret_cast(&bufferMs), sizeof(int32_t)); stream.read(reinterpret_cast(&latency), sizeof(int32_t)); - stream.read(reinterpret_cast(&volume), sizeof(double)); + stream.read(reinterpret_cast(&volume), sizeof(uint16_t)); + stream.read(reinterpret_cast(&muted), sizeof(bool)); } virtual uint32_t getSize() const { - return sizeof(int32_t) + sizeof(int32_t) + sizeof(double); + return sizeof(int32_t) + sizeof(int32_t) + sizeof(uint16_t) + sizeof(bool); } int32_t bufferMs; int32_t latency; - double volume; + uint16_t volume; + bool muted; protected: virtual void doserialize(std::ostream& stream) const { stream.write(reinterpret_cast(&bufferMs), sizeof(int32_t)); stream.write(reinterpret_cast(&latency), sizeof(int32_t)); - stream.write(reinterpret_cast(&volume), sizeof(double)); + stream.write(reinterpret_cast(&volume), sizeof(uint16_t)); + stream.write(reinterpret_cast(&muted), sizeof(bool)); } }; diff --git a/server/streamServer.cpp b/server/streamServer.cpp index cf8708af..03895ddd 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -86,6 +86,7 @@ void StreamServer::onDisconnect(ClientSession* connection) ClientInfoPtr client = Config::instance().getClientInfo(connection->macAddress); client->connected = false; gettimeofday(&client->lastSeen, NULL); + Config::instance().save(); json notification = JsonNotification::getJson("Client.OnDisconnect", client->toJson()); controlServer->send(notification.dump(4)); } @@ -93,9 +94,9 @@ void StreamServer::onDisconnect(ClientSession* connection) void StreamServer::onMessageReceived(ControlSession* connection, const std::string& message) { + JsonRequest request; try { - JsonRequest request; request.parse(message); //{"jsonrpc": "2.0", "method": "System.GetStatus", "id": 2} @@ -116,6 +117,14 @@ void StreamServer::onMessageReceived(ControlSession* connection, const std::stri logO << "method: " << request.method << ", " << "id: " << request.id << "\n"; json response; + ClientInfoPtr clientInfo = nullptr; + + if (request.method.find("Client.Set") == 0) + { + clientInfo = Config::instance().getClientInfo(request.getParam("client").get(), false); + if (clientInfo == nullptr) + throw JsonInternalErrorException("Client not found", request.id); + } if (request.method == "System.GetStatus") { @@ -139,33 +148,40 @@ void StreamServer::onMessageReceived(ControlSession* connection, const std::stri } else if (request.method == "Client.SetVolume") { - int volume = request.getParam("volume").get(); - logO << "client: " << request.getParam("client").get() << ", volume: " << volume << "\n"; - ClientSession* session = getClientSession(request.getParam("client").get()); -// if (session != NULL) - - response = volume; - } - else if (request.method == "Client.SetLatency") - { - int latency = request.getParam("latency").get(); - logO << "client: " << request.getParam("client").get() << ", latency: " << latency << "\n"; - response = latency; - } - else if (request.method == "Client.SetName") - { - string name = request.getParam("name").get(); - logO << "client: " << request.getParam("client").get() << ", name: " << name << "\n"; - response = name; + serverSettings_.volume = request.getParam("volume", 0, 100); + response = serverSettings_.volume; + clientInfo->volume.percent = serverSettings_.volume; } else if (request.method == "Client.SetMute") { - bool mute = request.getParam("mute").get(); - logO << "client: " << request.getParam("client").get() << ", mute: " << mute << "\n"; - response = mute; + serverSettings_.muted = request.getParam("mute", false, true); + response = serverSettings_.muted; + clientInfo->volume.muted = serverSettings_.muted; + } + else if (request.method == "Client.SetLatency") + { + serverSettings_.latency = request.getParam("latency", -10000, serverSettings_.bufferMs); + response = serverSettings_.latency; + clientInfo->latency = serverSettings_.latency; + } + else if (request.method == "Client.SetName") + { + clientInfo->name = request.getParam("name").get(); + response = clientInfo->name; } else - throw JsonMethodNotFoundException(request); + throw JsonMethodNotFoundException(request.id); + + if (clientInfo != nullptr) + { + ClientSession* session = getClientSession(request.getParam("client").get()); + if (session != NULL) + session->send(&serverSettings_); + + Config::instance().save(); + json notification = JsonNotification::getJson("Client.OnUpdate", clientInfo->toJson()); + controlServer->send(notification.dump()); + } connection->send(request.getResponse(response).dump()); } @@ -173,6 +189,11 @@ void StreamServer::onMessageReceived(ControlSession* connection, const std::stri { connection->send(e.getResponse().dump()); } + catch (const exception& e) + { + JsonInternalErrorException jsonException(e.what(), request.id); + connection->send(jsonException.getResponse().dump()); + } }