configuration is stored in file snapserver.conf

This commit is contained in:
badaix 2019-10-06 13:28:22 +02:00
parent fa508eafba
commit 72bd17cb20
11 changed files with 266 additions and 89 deletions

View file

@ -4,7 +4,7 @@
<title>Snapcast Interface</title>
Taken from <a href="https://github.com/derglaus/snapcast-websockets-ui">derglaus/snapcast-websockets-ui</a> for testing purposes
<script>
var connection = new WebSocket('ws://127.0.0.1:8080/jsonrpc');
var connection = new WebSocket('ws://127.0.0.1:1780/jsonrpc');
var server;
connection.onmessage = function (e) {

View file

@ -32,8 +32,9 @@ using namespace std;
using json = nlohmann::json;
ControlServer::ControlServer(boost::asio::io_context* io_context, size_t port, ControlMessageReceiver* controlMessageReceiver)
: io_context_(io_context), port_(port), controlMessageReceiver_(controlMessageReceiver)
ControlServer::ControlServer(boost::asio::io_context* io_context, const ServerSettings::TcpSettings& tcp_settings,
const ServerSettings::HttpSettings& http_settings, ControlMessageReceiver* controlMessageReceiver)
: io_context_(io_context), controlMessageReceiver_(controlMessageReceiver), tcp_settings_(tcp_settings), http_settings_(http_settings)
{
}
@ -95,7 +96,7 @@ void ControlServer::startAccept()
auto accept_handler_http = [this](error_code ec, tcp::socket socket) {
if (!ec)
handleAccept<ControlSessionHttp>(std::move(socket));
handleAccept<ControlSessionHttp>(std::move(socket), http_settings_);
else
LOG(ERROR) << "Error while accepting socket connection: " << ec.message() << "\n";
};
@ -114,8 +115,8 @@ void ControlServer::startAccept()
}
template <typename SessionType>
void ControlServer::handleAccept(tcp::socket socket)
template <typename SessionType, typename... Args>
void ControlServer::handleAccept(tcp::socket socket, Args&&... args)
{
try
{
@ -126,7 +127,7 @@ void ControlServer::handleAccept(tcp::socket socket)
setsockopt(socket.native_handle(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
// socket->set_option(boost::asio::ip::tcp::no_delay(false));
SLOG(NOTICE) << "ControlServer::NewConnection: " << socket.remote_endpoint().address().to_string() << endl;
shared_ptr<SessionType> session = make_shared<SessionType>(this, std::move(socket));
shared_ptr<SessionType> session = make_shared<SessionType>(this, std::move(socket), std::forward<Args>(args)...);
{
std::lock_guard<std::recursive_mutex> mlock(session_mutex_);
session->start();
@ -179,10 +180,10 @@ std::pair<acceptor_ptr, acceptor_ptr> ControlServer::createAcceptors(size_t port
void ControlServer::start()
{
// TODO: should be possible to be disabled
acceptor_tcp_ = createAcceptors(port_);
// TODO: make port configurable, should be possible to be disabled
acceptor_http_ = createAcceptors(8080);
if (tcp_settings_.enabled)
acceptor_tcp_ = createAcceptors(tcp_settings_.port);
if (http_settings_.enabled)
acceptor_http_ = createAcceptors(http_settings_.port);
startAccept();
}

View file

@ -33,6 +33,7 @@
#include "message/codecHeader.h"
#include "message/message.h"
#include "message/serverSettings.h"
#include "server_settings.hpp"
using boost::asio::ip::tcp;
using acceptor_ptr = std::unique_ptr<tcp::acceptor>;
@ -44,7 +45,8 @@ using acceptor_ptr = std::unique_ptr<tcp::acceptor>;
class ControlServer : public ControlMessageReceiver
{
public:
ControlServer(boost::asio::io_context* io_context, size_t port, ControlMessageReceiver* controlMessageReceiver = nullptr);
ControlServer(boost::asio::io_context* io_context, const ServerSettings::TcpSettings& tcp_settings, const ServerSettings::HttpSettings& http_settings,
ControlMessageReceiver* controlMessageReceiver = nullptr);
virtual ~ControlServer();
void start();
@ -60,9 +62,8 @@ private:
void startAccept();
std::pair<acceptor_ptr, acceptor_ptr> createAcceptors(size_t port);
template <typename SessionType>
void handleAccept(tcp::socket socket);
// void handleAcceptWs(tcp::socket socket);
template <typename SessionType, typename... Args>
void handleAccept(tcp::socket socket, Args&&... args);
void cleanup();
mutable std::recursive_mutex session_mutex_;
@ -72,7 +73,8 @@ private:
std::pair<acceptor_ptr, acceptor_ptr> acceptor_http_;
boost::asio::io_context* io_context_;
size_t port_;
ServerSettings::TcpSettings tcp_settings_;
ServerSettings::HttpSettings http_settings_;
ControlMessageReceiver* controlMessageReceiver_;
};

View file

@ -21,6 +21,7 @@
#include "common/queue.h"
#include "message/message.h"
#include "server_settings.hpp"
#include <atomic>
#include <boost/asio.hpp>
#include <condition_variable>
@ -30,7 +31,6 @@
#include <string>
#include <thread>
using boost::asio::ip::tcp;

View file

@ -98,7 +98,8 @@ std::string path_cat(boost::beast::string_view base, boost::beast::string_view p
}
} // namespace
ControlSessionHttp::ControlSessionHttp(ControlMessageReceiver* receiver, tcp::socket&& socket) : ControlSession(receiver), socket_(std::move(socket))
ControlSessionHttp::ControlSessionHttp(ControlMessageReceiver* receiver, tcp::socket&& socket, const ServerSettings::HttpSettings& settings)
: ControlSession(receiver), socket_(std::move(socket)), settings_(settings)
{
LOG(DEBUG) << "ControlSessionHttp\n";
}
@ -183,10 +184,11 @@ void ControlSessionHttp::handle_request(http::request<Body, http::basic_fields<A
if (req.target().empty() || req.target()[0] != '/' || req.target().find("..") != beast::string_view::npos)
return send(bad_request("Illegal request-target"));
// TODO: configurable, enable/disable
std::string doc_root = "../control";
if (settings_.doc_root.empty())
return send(not_found(req.target()));
// Build the path to the requested file
std::string path = path_cat(doc_root, req.target());
std::string path = path_cat(settings_.doc_root, req.target());
if (req.target().back() == '/')
path.append("index.html");

View file

@ -39,7 +39,7 @@ class ControlSessionHttp : public ControlSession, public std::enable_shared_from
{
public:
/// ctor. Received message from the client are passed to MessageReceiver
ControlSessionHttp(ControlMessageReceiver* receiver, tcp::socket&& socket);
ControlSessionHttp(ControlMessageReceiver* receiver, tcp::socket&& socket, const ServerSettings::HttpSettings& settings);
~ControlSessionHttp() override;
void start() override;
void stop() override;
@ -71,6 +71,7 @@ protected:
protected:
tcp::socket socket_;
beast::flat_buffer buffer_;
ServerSettings::HttpSettings settings_;
};

View file

@ -0,0 +1,63 @@
/***
This file is part of snapcast
Copyright (C) 2014-2019 Johannes Pohl
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef SERVER_SETTINGS_HPP
#define SERVER_SETTINGS_HPP
#include <string>
#include <vector>
struct ServerSettings
{
struct HttpSettings
{
bool enabled{true};
size_t port{1780};
std::string doc_root{""};
};
struct TcpSettings
{
bool enabled{true};
size_t port{1705};
};
struct StreamSettings
{
size_t port{1704};
std::vector<std::string> pcmStreams;
std::string codec{"flac"};
int32_t bufferMs{1000};
std::string sampleFormat{"48000:16:2"};
size_t streamReadMs{20};
bool sendAudioToMutedClients{false};
};
struct LoggingSettings
{
bool debug{false};
std::string debug_logfile{""};
};
HttpSettings http;
TcpSettings tcp;
StreamSettings stream;
LoggingSettings logging;
};
#endif

View file

@ -20,7 +20,7 @@
#include <memory>
#include <sys/resource.h>
#include "popl.hpp"
#include "../externals/popl/include/popl.hpp"
#ifdef HAS_DAEMON
#include "common/daemon.h"
#endif
@ -31,6 +31,7 @@
#include "common/utils/string_utils.h"
#include "encoder/encoderFactory.h"
#include "message/message.h"
#include "server_settings.hpp"
#include "streamServer.h"
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
#include "publishZeroConf/publishmDNS.h"
@ -55,35 +56,57 @@ int main(int argc, char* argv[])
int exitcode = EXIT_SUCCESS;
try
{
StreamServerSettings settings;
ServerSettings settings;
std::string pcmStream = "pipe:///tmp/snapfifo?name=default";
std::string config_file = "/etc/snapserver.conf";
OptionParser op("Allowed options");
auto helpSwitch = op.add<Switch>("h", "help", "Produce help message");
auto groffSwitch = op.add<Switch, Attribute::hidden>("", "groff", "produce groff message");
auto debugOption = op.add<Implicit<string>, Attribute::hidden>("", "debug", "enable debug logging", "");
auto versionSwitch = op.add<Switch>("v", "version", "Show version number");
op.add<Value<size_t>>("p", "port", "Server port", settings.port, &settings.port);
op.add<Value<size_t>>("", "controlPort", "Remote control port", settings.controlPort, &settings.controlPort);
auto streamValue = op.add<Value<string>>(
"s", "stream", "URI of the PCM input stream.\nFormat: TYPE://host/path?name=NAME\n[&codec=CODEC]\n[&sampleformat=SAMPLEFORMAT]", pcmStream,
&pcmStream);
op.add<Value<string>>("", "sampleformat", "Default sample format", settings.sampleFormat, &settings.sampleFormat);
op.add<Value<string>>("c", "codec", "Default transport codec\n(flac|ogg|pcm)[:options]\nType codec:? to get codec specific options", settings.codec,
&settings.codec);
op.add<Value<size_t>>("", "streamBuffer", "Default stream read buffer [ms]", settings.streamReadMs, &settings.streamReadMs);
op.add<Value<int>>("b", "buffer", "Buffer [ms]", settings.bufferMs, &settings.bufferMs);
op.add<Switch>("", "sendToMuted", "Send audio to muted clients", &settings.sendAudioToMutedClients);
#ifdef HAS_DAEMON
int processPriority(0);
auto daemonOption = op.add<Implicit<int>>("d", "daemon", "Daemonize\noptional process priority [-20..19]", 0, &processPriority);
auto userValue = op.add<Value<string>>("", "user", "the user[:group] to run snapserver as when daemonized", "");
#endif
op.add<Value<string>>("c", "config", "path to the configuration file", config_file, &config_file);
// debug settings
OptionParser conf("");
conf.add<Switch>("", "logging.debug", "enable debug logging", &settings.logging.debug);
conf.add<Value<string>>("", "logging.debug_logfile", "log file name for the debug logs (debug must be enabled)", settings.logging.debug_logfile,
&settings.logging.debug_logfile);
// stream settings
conf.add<Value<size_t>>("p", "stream.port", "Server port", settings.stream.port, &settings.stream.port);
conf.add<Value<size_t>>("", "stream.controlPort", "Remote control port", settings.tcp.port, &settings.tcp.port);
auto streamValue = conf.add<Value<string>>(
"s", "stream.stream", "URI of the PCM input stream.\nFormat: TYPE://host/path?name=NAME\n[&codec=CODEC]\n[&sampleformat=SAMPLEFORMAT]", pcmStream,
&pcmStream);
conf.add<Value<string>>("", "stream.sampleformat", "Default sample format", settings.stream.sampleFormat, &settings.stream.sampleFormat);
conf.add<Value<string>>("c", "stream.codec", "Default transport codec\n(flac|ogg|pcm)[:options]\nType codec:? to get codec specific options",
settings.stream.codec, &settings.stream.codec);
conf.add<Value<size_t>>("", "stream.streamBuffer", "Default stream read buffer [ms]", settings.stream.streamReadMs, &settings.stream.streamReadMs);
conf.add<Value<int>>("b", "stream.buffer", "Buffer [ms]", settings.stream.bufferMs, &settings.stream.bufferMs);
conf.add<Switch>("", "stream.sendToMuted", "Send audio to muted clients", &settings.stream.sendAudioToMutedClients);
// HTTP RPC settings
conf.add<Switch>("", "http.enabled", "enable HTTP Json RPC (HTTP POST and websockets)", &settings.http.enabled);
conf.add<Value<size_t>>("", "http.port", "which port the server should listen to", settings.http.port, &settings.http.port);
conf.add<Value<string>>("", "http.doc_root", "serve a website from the doc_root location", settings.http.doc_root, &settings.http.doc_root);
// TCP RPC settings
conf.add<Switch>("", "tcp.enabled", "enable TCP Json RPC)", &settings.tcp.enabled);
conf.add<Value<size_t>>("", "tcp.port", "which port the server should listen to", settings.tcp.port, &settings.tcp.port);
// TODO: Should be possible to override settings on command line
try
{
op.parse(argc, argv);
conf.parse(config_file);
}
catch (const std::invalid_argument& e)
{
@ -116,34 +139,25 @@ int main(int argc, char* argv[])
exit(EXIT_SUCCESS);
}
if (!streamValue->is_set())
settings.pcmStreams.push_back(streamValue->value());
for (size_t n = 0; n < streamValue->count(); ++n)
{
cout << streamValue->value(n) << "\n";
settings.pcmStreams.push_back(streamValue->value(n));
}
if (settings.codec.find(":?") != string::npos)
if (settings.stream.codec.find(":?") != string::npos)
{
EncoderFactory encoderFactory;
std::unique_ptr<Encoder> encoder(encoderFactory.createEncoder(settings.codec));
std::unique_ptr<Encoder> encoder(encoderFactory.createEncoder(settings.stream.codec));
if (encoder)
{
cout << "Options for codec \"" << encoder->name() << "\":\n"
<< " " << encoder->getAvailableOptions() << "\n"
<< " Default: \"" << encoder->getDefaultOptions() << "\"\n";
}
return 1;
exit(EXIT_SUCCESS);
}
AixLog::Log::init<AixLog::SinkNative>("snapserver", AixLog::Severity::trace, AixLog::Type::special);
if (debugOption->is_set())
if (settings.logging.debug)
{
AixLog::Log::instance().add_logsink<AixLog::SinkCout>(AixLog::Severity::trace, AixLog::Type::all, "%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag_func)");
if (!debugOption->value().empty())
AixLog::Log::instance().add_logsink<AixLog::SinkFile>(AixLog::Severity::trace, AixLog::Type::all, debugOption->value(),
if (!settings.logging.debug_logfile.empty())
AixLog::Log::instance().add_logsink<AixLog::SinkFile>(AixLog::Severity::trace, AixLog::Type::all, settings.logging.debug_logfile,
"%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag_func)");
}
else
@ -151,6 +165,14 @@ int main(int argc, char* argv[])
AixLog::Log::instance().add_logsink<AixLog::SinkCout>(AixLog::Severity::info, AixLog::Type::all, "%Y-%m-%d %H-%M-%S [#severity]");
}
if (!streamValue->is_set())
settings.stream.pcmStreams.push_back(streamValue->value());
for (size_t n = 0; n < streamValue->count(); ++n)
{
LOG(INFO) << "Adding stream: " << streamValue->value(n) << "\n";
settings.stream.pcmStreams.push_back(streamValue->value(n));
}
signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler);
@ -194,12 +216,26 @@ int main(int argc, char* argv[])
#if defined(HAS_AVAHI) || defined(HAS_BONJOUR)
PublishZeroConf publishZeroConfg("Snapcast");
publishZeroConfg.publish({mDNSService("_snapcast._tcp", settings.port), mDNSService("_snapcast-jsonrpc._tcp", settings.controlPort),
mDNSService("_snapcastjsonrpc._tcp", settings.controlPort)});
vector<mDNSService> dns_services;
dns_services.emplace_back("_snapcast._tcp", settings.stream.port);
dns_services.emplace_back("_snapcast-stream._tcp", settings.stream.port);
if (settings.tcp.enabled)
{
dns_services.emplace_back("_snapcast-jsonrpc._tcp", settings.tcp.port);
dns_services.emplace_back("_snapcast-tcp._tcp", settings.tcp.port);
}
if (settings.http.enabled)
{
dns_services.emplace_back("_snapcast-http._tcp", settings.http.port);
}
publishZeroConfg.publish(dns_services);
#endif
if (settings.bufferMs < 400)
settings.bufferMs = 400;
if (settings.stream.bufferMs < 400)
{
LOG(WARNING) << "Buffer is less than 400ms, changing to 400ms\n";
settings.stream.bufferMs = 400;
}
boost::asio::io_context io_context;
std::unique_ptr<StreamServer> streamServer(new StreamServer(&io_context, settings));

87
server/snapserver.conf Normal file
View file

@ -0,0 +1,87 @@
##################################
### ###
### Snapserver config file ###
### ###
##################################
# default values are commented
# to change them, just uncomment
# HTTP RPC ####################################################################
#
[http]
# enable HTTP Json RPC (HTTP POST and websockets)
enabled = true
# address to listen on
# TODO: not implemented yet
bind_to_address = 127.0.0.1
# which port the server should listen to
port = 1780
# serve a website from the doc_root location
doc_root = /home/johannes/Develop/snapcast/control
#
###############################################################################
# TCP RPC #####################################################################
#
[tcp]
# enable TCP Json RPC
enabled = true_
# address to listen on
# TODO: not implemented yet
bind_to_address = 127.0.0.1
# which port the server should listen to
port = 1705
#
###############################################################################
# Stream settings #############################################################
#
[stream]
# address to listen on
# TODO: not implemented yet
#bind_to_address = 0.0.0.0
# which port the server should listen to
#port = 1704
# stream URI of the PCM input stream, can be configured multiple times
# Format: TYPE://host/path?name=NAME[&codec=CODEC][&sampleformat=SAMPLEFORMAT]
stream = pipe:///tmp/snapfifo?name=default
stream = pipe:///tmp/snapfifo2?name=default2
# Default sample format
#sampleformat = 48000:16:2
# Default transport codec
# (flac|ogg|pcm)[:options]
# Type codec:? to get codec specific options
#codec = flac
# Default stream read buffer [ms]
#streamBuffer = 20
# Buffer [ms]
#buffer = 1000
# Send audio to muted clients
#sendToMuted = false
#
###############################################################################
# Logging options #############################################################
#
[logging]
# enable debug logging
#debug = false
# log file name for the debug logs (debug must be enabled)
#debug_logfile =
#
###############################################################################

View file

@ -29,8 +29,8 @@ using namespace std;
using json = nlohmann::json;
StreamServer::StreamServer(boost::asio::io_context* io_context, const StreamServerSettings& streamServerSettings)
: io_context_(io_context), acceptor_v4_(nullptr), acceptor_v6_(nullptr), settings_(streamServerSettings)
StreamServer::StreamServer(boost::asio::io_context* io_context, const ServerSettings& serverSettings)
: io_context_(io_context), acceptor_v4_(nullptr), acceptor_v6_(nullptr), settings_(serverSettings)
{
}
@ -81,7 +81,7 @@ void StreamServer::onChunkRead(const PcmStream* pcmStream, msg::PcmChunk* chunk,
std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
for (auto s : sessions_)
{
if (!settings_.sendAudioToMutedClients)
if (!settings_.stream.sendAudioToMutedClients)
{
GroupPtr group = Config::instance().getGroupFromClient(s->clientId);
if (group)
@ -195,9 +195,9 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
int latency = request->params().get("latency");
if (latency < -10000)
latency = -10000;
else if (latency > settings_.bufferMs)
latency = settings_.bufferMs;
clientInfo->config.latency = latency; //, -10000, settings_.bufferMs);
else if (latency > settings_.stream.bufferMs)
latency = settings_.stream.bufferMs;
clientInfo->config.latency = latency; //, -10000, settings_.stream.bufferMs);
result["latency"] = clientInfo->config.latency;
notification.reset(
new jsonrpcpp::Notification("Client.OnLatencyChanged", jsonrpcpp::Parameter("id", clientInfo->id, "latency", clientInfo->config.latency)));
@ -223,7 +223,7 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
if (session != nullptr)
{
auto serverSettings = make_shared<msg::ServerSettings>();
serverSettings->setBufferMs(settings_.bufferMs);
serverSettings->setBufferMs(settings_.stream.bufferMs);
serverSettings->setVolume(clientInfo->config.volume.percent);
GroupPtr group = Config::instance().getGroupFromClient(clientInfo);
serverSettings->setMuted(clientInfo->config.volume.muted || group->muted);
@ -274,7 +274,7 @@ void StreamServer::ProcessRequest(const jsonrpcpp::request_ptr request, jsonrpcp
if (session != nullptr)
{
auto serverSettings = make_shared<msg::ServerSettings>();
serverSettings->setBufferMs(settings_.bufferMs);
serverSettings->setBufferMs(settings_.stream.bufferMs);
serverSettings->setVolume(client->config.volume.percent);
GroupPtr group = Config::instance().getGroupFromClient(client);
serverSettings->setMuted(client->config.volume.muted || group->muted);
@ -667,7 +667,7 @@ void StreamServer::onMessageReceived(StreamSession* streamSession, const msg::Ba
serverSettings->setVolume(client->config.volume.percent);
serverSettings->setMuted(client->config.volume.muted || group->muted);
serverSettings->setLatency(client->config.latency);
serverSettings->setBufferMs(settings_.bufferMs);
serverSettings->setBufferMs(settings_.stream.bufferMs);
serverSettings->refersTo = helloMsg.id;
streamSession->sendAsync(serverSettings);
@ -793,7 +793,7 @@ void StreamServer::handleAccept(socket_ptr socket)
SLOG(NOTICE) << "StreamServer::NewConnection: " << socket->remote_endpoint().address().to_string() << endl;
shared_ptr<StreamSession> session = make_shared<StreamSession>(this, socket);
session->setBufferMs(settings_.bufferMs);
session->setBufferMs(settings_.stream.bufferMs);
session->start();
std::lock_guard<std::recursive_mutex> mlock(sessionsMutex_);
@ -811,12 +811,12 @@ void StreamServer::start()
{
try
{
controlServer_.reset(new ControlServer(io_context_, settings_.controlPort, this));
controlServer_.reset(new ControlServer(io_context_, settings_.tcp, settings_.http, this));
controlServer_->start();
streamManager_.reset(new StreamManager(this, settings_.sampleFormat, settings_.codec, settings_.streamReadMs));
streamManager_.reset(new StreamManager(this, settings_.stream.sampleFormat, settings_.stream.codec, settings_.stream.streamReadMs));
// throw SnapException("xxx");
for (const auto& streamUri : settings_.pcmStreams)
for (const auto& streamUri : settings_.stream.pcmStreams)
{
PcmStreamPtr stream = streamManager_->addStream(streamUri);
if (stream)
@ -825,7 +825,7 @@ void StreamServer::start()
streamManager_->start();
bool is_v6_only(true);
tcp::endpoint endpoint_v6(tcp::v6(), settings_.port);
tcp::endpoint endpoint_v6(tcp::v6(), settings_.stream.port);
try
{
acceptor_v6_ = make_shared<tcp::acceptor>(*io_context_, endpoint_v6);
@ -843,7 +843,7 @@ void StreamServer::start()
if (!acceptor_v6_ || is_v6_only)
{
tcp::endpoint endpoint_v4(tcp::v4(), settings_.port);
tcp::endpoint endpoint_v4(tcp::v4(), settings_.stream.port);
try
{
acceptor_v4_ = make_shared<tcp::acceptor>(*io_context_, endpoint_v4);

View file

@ -34,6 +34,7 @@
#include "message/codecHeader.h"
#include "message/message.h"
#include "message/serverSettings.h"
#include "server_settings.hpp"
#include "streamSession.h"
#include "streamreader/streamManager.h"
@ -42,22 +43,6 @@ using boost::asio::ip::tcp;
typedef std::shared_ptr<tcp::socket> socket_ptr;
typedef std::shared_ptr<StreamSession> session_ptr;
struct StreamServerSettings
{
StreamServerSettings()
: port(1704), controlPort(1705), codec("flac"), bufferMs(1000), sampleFormat("48000:16:2"), streamReadMs(20), sendAudioToMutedClients(false)
{
}
size_t port;
size_t controlPort;
std::vector<std::string> pcmStreams;
std::string codec;
int32_t bufferMs;
std::string sampleFormat;
size_t streamReadMs;
bool sendAudioToMutedClients;
};
/// Forwars PCM data to the connected clients
/**
@ -69,7 +54,7 @@ struct StreamServerSettings
class StreamServer : public MessageReceiver, ControlMessageReceiver, PcmListener
{
public:
StreamServer(boost::asio::io_context* io_context, const StreamServerSettings& streamServerSettings);
StreamServer(boost::asio::io_context* io_context, const ServerSettings& serverSettings);
virtual ~StreamServer();
void start();
@ -103,7 +88,7 @@ private:
std::shared_ptr<tcp::acceptor> acceptor_v4_;
std::shared_ptr<tcp::acceptor> acceptor_v6_;
StreamServerSettings settings_;
ServerSettings settings_;
Queue<std::shared_ptr<msg::BaseMessage>> messages_;
std::unique_ptr<ControlServer> controlServer_;
std::unique_ptr<StreamManager> streamManager_;