mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-19 12:06:15 +02:00
control player settings
This commit is contained in:
parent
3f1a6d29d8
commit
5d68e36718
4 changed files with 71 additions and 33 deletions
|
@ -23,7 +23,6 @@
|
||||||
#include "decoder/oggDecoder.h"
|
#include "decoder/oggDecoder.h"
|
||||||
#include "decoder/pcmDecoder.h"
|
#include "decoder/pcmDecoder.h"
|
||||||
#include "decoder/flacDecoder.h"
|
#include "decoder/flacDecoder.h"
|
||||||
#include "alsaPlayer.h"
|
|
||||||
#include "timeProvider.h"
|
#include "timeProvider.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/snapException.h"
|
#include "common/snapException.h"
|
||||||
|
@ -32,11 +31,12 @@
|
||||||
#include "message/request.h"
|
#include "message/request.h"
|
||||||
#include "message/ack.h"
|
#include "message/ack.h"
|
||||||
#include "message/command.h"
|
#include "message/command.h"
|
||||||
|
#include "message/hello.h"
|
||||||
|
|
||||||
using namespace std;
|
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);
|
TimeProvider::getInstance().setDiffToServer((reply.latency - latency) * 1000 / 2);
|
||||||
// logO << "diff to server [ms]: " << (float)TimeProvider::getInstance().getDiffToServer<chronos::usec>().count() / 1000.f << "\n";
|
// logO << "diff to server [ms]: " << (float)TimeProvider::getInstance().getDiffToServer<chronos::usec>().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 (baseMessage.type != message_type::kTime)
|
||||||
if (sendTimeSyncMessage(1000))
|
if (sendTimeSyncMessage(1000))
|
||||||
|
@ -167,9 +179,9 @@ void Controller::worker()
|
||||||
stream_ = new Stream(*sampleFormat_);
|
stream_ = new Stream(*sampleFormat_);
|
||||||
stream_->setBufferLen(serverSettings->bufferMs - latency_);
|
stream_->setBufferLen(serverSettings->bufferMs - latency_);
|
||||||
|
|
||||||
Player player(pcmDevice_, stream_);
|
player_.reset(new Player(pcmDevice_, stream_));
|
||||||
player.setVolume(serverSettings->volume);
|
player_->setVolume(serverSettings->volume);
|
||||||
player.start();
|
player_->start();
|
||||||
|
|
||||||
msg::Command startStream("startStream");
|
msg::Command startStream("startStream");
|
||||||
shared_ptr<msg::Ack> ackMsg(NULL);
|
shared_ptr<msg::Ack> ackMsg(NULL);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "clientConnection.h"
|
#include "clientConnection.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "pcmDevice.h"
|
#include "pcmDevice.h"
|
||||||
|
#include "alsaPlayer.h"
|
||||||
|
|
||||||
|
|
||||||
/// Forwards PCM data to the audio player
|
/// Forwards PCM data to the audio player
|
||||||
|
@ -61,6 +62,7 @@ private:
|
||||||
Decoder* decoder_;
|
Decoder* decoder_;
|
||||||
PcmDevice pcmDevice_;
|
PcmDevice pcmDevice_;
|
||||||
size_t latency_;
|
size_t latency_;
|
||||||
|
std::unique_ptr<Player> player_;
|
||||||
|
|
||||||
std::exception exception_;
|
std::exception exception_;
|
||||||
bool asyncException_;
|
bool asyncException_;
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace msg
|
||||||
class ServerSettings : public BaseMessage
|
class ServerSettings : public BaseMessage
|
||||||
{
|
{
|
||||||
public:
|
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<char*>(&bufferMs), sizeof(int32_t));
|
stream.read(reinterpret_cast<char*>(&bufferMs), sizeof(int32_t));
|
||||||
stream.read(reinterpret_cast<char*>(&latency), sizeof(int32_t));
|
stream.read(reinterpret_cast<char*>(&latency), sizeof(int32_t));
|
||||||
stream.read(reinterpret_cast<char*>(&volume), sizeof(double));
|
stream.read(reinterpret_cast<char*>(&volume), sizeof(uint16_t));
|
||||||
|
stream.read(reinterpret_cast<char*>(&muted), sizeof(bool));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint32_t getSize() const
|
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 bufferMs;
|
||||||
int32_t latency;
|
int32_t latency;
|
||||||
double volume;
|
uint16_t volume;
|
||||||
|
bool muted;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void doserialize(std::ostream& stream) const
|
virtual void doserialize(std::ostream& stream) const
|
||||||
{
|
{
|
||||||
stream.write(reinterpret_cast<const char*>(&bufferMs), sizeof(int32_t));
|
stream.write(reinterpret_cast<const char*>(&bufferMs), sizeof(int32_t));
|
||||||
stream.write(reinterpret_cast<const char*>(&latency), sizeof(int32_t));
|
stream.write(reinterpret_cast<const char*>(&latency), sizeof(int32_t));
|
||||||
stream.write(reinterpret_cast<const char*>(&volume), sizeof(double));
|
stream.write(reinterpret_cast<const char*>(&volume), sizeof(uint16_t));
|
||||||
|
stream.write(reinterpret_cast<const char*>(&muted), sizeof(bool));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ void StreamServer::onDisconnect(ClientSession* connection)
|
||||||
ClientInfoPtr client = Config::instance().getClientInfo(connection->macAddress);
|
ClientInfoPtr client = Config::instance().getClientInfo(connection->macAddress);
|
||||||
client->connected = false;
|
client->connected = false;
|
||||||
gettimeofday(&client->lastSeen, NULL);
|
gettimeofday(&client->lastSeen, NULL);
|
||||||
|
Config::instance().save();
|
||||||
json notification = JsonNotification::getJson("Client.OnDisconnect", client->toJson());
|
json notification = JsonNotification::getJson("Client.OnDisconnect", client->toJson());
|
||||||
controlServer->send(notification.dump(4));
|
controlServer->send(notification.dump(4));
|
||||||
}
|
}
|
||||||
|
@ -93,9 +94,9 @@ void StreamServer::onDisconnect(ClientSession* connection)
|
||||||
|
|
||||||
void StreamServer::onMessageReceived(ControlSession* connection, const std::string& message)
|
void StreamServer::onMessageReceived(ControlSession* connection, const std::string& message)
|
||||||
{
|
{
|
||||||
|
JsonRequest request;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
JsonRequest request;
|
|
||||||
request.parse(message);
|
request.parse(message);
|
||||||
|
|
||||||
//{"jsonrpc": "2.0", "method": "System.GetStatus", "id": 2}
|
//{"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";
|
logO << "method: " << request.method << ", " << "id: " << request.id << "\n";
|
||||||
|
|
||||||
json response;
|
json response;
|
||||||
|
ClientInfoPtr clientInfo = nullptr;
|
||||||
|
|
||||||
|
if (request.method.find("Client.Set") == 0)
|
||||||
|
{
|
||||||
|
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>(), false);
|
||||||
|
if (clientInfo == nullptr)
|
||||||
|
throw JsonInternalErrorException("Client not found", request.id);
|
||||||
|
}
|
||||||
|
|
||||||
if (request.method == "System.GetStatus")
|
if (request.method == "System.GetStatus")
|
||||||
{
|
{
|
||||||
|
@ -139,33 +148,40 @@ void StreamServer::onMessageReceived(ControlSession* connection, const std::stri
|
||||||
}
|
}
|
||||||
else if (request.method == "Client.SetVolume")
|
else if (request.method == "Client.SetVolume")
|
||||||
{
|
{
|
||||||
int volume = request.getParam("volume").get<int>();
|
serverSettings_.volume = request.getParam<uint16_t>("volume", 0, 100);
|
||||||
logO << "client: " << request.getParam("client").get<string>() << ", volume: " << volume << "\n";
|
response = serverSettings_.volume;
|
||||||
ClientSession* session = getClientSession(request.getParam("client").get<string>());
|
clientInfo->volume.percent = serverSettings_.volume;
|
||||||
// if (session != NULL)
|
|
||||||
|
|
||||||
response = volume;
|
|
||||||
}
|
|
||||||
else if (request.method == "Client.SetLatency")
|
|
||||||
{
|
|
||||||
int latency = request.getParam("latency").get<int>();
|
|
||||||
logO << "client: " << request.getParam("client").get<string>() << ", latency: " << latency << "\n";
|
|
||||||
response = latency;
|
|
||||||
}
|
|
||||||
else if (request.method == "Client.SetName")
|
|
||||||
{
|
|
||||||
string name = request.getParam("name").get<string>();
|
|
||||||
logO << "client: " << request.getParam("client").get<string>() << ", name: " << name << "\n";
|
|
||||||
response = name;
|
|
||||||
}
|
}
|
||||||
else if (request.method == "Client.SetMute")
|
else if (request.method == "Client.SetMute")
|
||||||
{
|
{
|
||||||
bool mute = request.getParam("mute").get<bool>();
|
serverSettings_.muted = request.getParam<bool>("mute", false, true);
|
||||||
logO << "client: " << request.getParam("client").get<string>() << ", mute: " << mute << "\n";
|
response = serverSettings_.muted;
|
||||||
response = mute;
|
clientInfo->volume.muted = serverSettings_.muted;
|
||||||
|
}
|
||||||
|
else if (request.method == "Client.SetLatency")
|
||||||
|
{
|
||||||
|
serverSettings_.latency = request.getParam<int>("latency", -10000, serverSettings_.bufferMs);
|
||||||
|
response = serverSettings_.latency;
|
||||||
|
clientInfo->latency = serverSettings_.latency;
|
||||||
|
}
|
||||||
|
else if (request.method == "Client.SetName")
|
||||||
|
{
|
||||||
|
clientInfo->name = request.getParam("name").get<string>();
|
||||||
|
response = clientInfo->name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw JsonMethodNotFoundException(request);
|
throw JsonMethodNotFoundException(request.id);
|
||||||
|
|
||||||
|
if (clientInfo != nullptr)
|
||||||
|
{
|
||||||
|
ClientSession* session = getClientSession(request.getParam("client").get<string>());
|
||||||
|
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());
|
connection->send(request.getResponse(response).dump());
|
||||||
}
|
}
|
||||||
|
@ -173,6 +189,11 @@ void StreamServer::onMessageReceived(ControlSession* connection, const std::stri
|
||||||
{
|
{
|
||||||
connection->send(e.getResponse().dump());
|
connection->send(e.getResponse().dump());
|
||||||
}
|
}
|
||||||
|
catch (const exception& e)
|
||||||
|
{
|
||||||
|
JsonInternalErrorException jsonException(e.what(), request.id);
|
||||||
|
connection->send(jsonException.getResponse().dump());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue