mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-11 16:16:42 +02:00
Settings can be overwritten on command line
make pidfile and persistant data dir confgurable
This commit is contained in:
parent
0c25a7a42d
commit
7376c7709c
8 changed files with 45 additions and 21 deletions
|
@ -191,6 +191,7 @@ int main(int argc, char** argv)
|
||||||
group = user_group[1];
|
group = user_group[1];
|
||||||
}
|
}
|
||||||
daemon = std::make_unique<Daemon>(user, group, pidFile);
|
daemon = std::make_unique<Daemon>(user, group, pidFile);
|
||||||
|
SLOG(NOTICE) << "daemonizing" << std::endl;
|
||||||
daemon->daemonize();
|
daemon->daemonize();
|
||||||
if (processPriority < -20)
|
if (processPriority < -20)
|
||||||
processPriority = -20;
|
processPriority = -20;
|
||||||
|
|
|
@ -148,7 +148,7 @@ void Daemon::daemonize()
|
||||||
|
|
||||||
/// Try to lock file
|
/// Try to lock file
|
||||||
if (lockf(pidFilehandle_, F_TLOCK, 0) == -1)
|
if (lockf(pidFilehandle_, F_TLOCK, 0) == -1)
|
||||||
throw SnapException("Could not lock PID lock file \"" + pidfile_ + "\"");
|
throw SnapException("Could not lock PID lock file \"" + pidfile_ + "\". Is the daemon already running?");
|
||||||
|
|
||||||
char str[10];
|
char str[10];
|
||||||
/// Get and format PID
|
/// Get and format PID
|
||||||
|
|
|
@ -338,6 +338,9 @@ public:
|
||||||
/// @param argv command line arguments
|
/// @param argv command line arguments
|
||||||
void parse(int argc, const char* const argv[]);
|
void parse(int argc, const char* const argv[]);
|
||||||
|
|
||||||
|
/// Delete all parsed options
|
||||||
|
void reset();
|
||||||
|
|
||||||
/// Produce a help message
|
/// Produce a help message
|
||||||
/// @param max_attribute show options up to this level (optional, advanced, expert)
|
/// @param max_attribute show options up to this level (optional, advanced, expert)
|
||||||
/// @return the help message
|
/// @return the help message
|
||||||
|
@ -989,11 +992,6 @@ inline void OptionParser::parse(const std::string& ini_filename)
|
||||||
|
|
||||||
inline void OptionParser::parse(int argc, const char* const argv[])
|
inline void OptionParser::parse(int argc, const char* const argv[])
|
||||||
{
|
{
|
||||||
unknown_options_.clear();
|
|
||||||
non_option_args_.clear();
|
|
||||||
for (auto& opt : options_)
|
|
||||||
opt->clear();
|
|
||||||
|
|
||||||
for (int n = 1; n < argc; ++n)
|
for (int n = 1; n < argc; ++n)
|
||||||
{
|
{
|
||||||
const std::string arg(argv[n]);
|
const std::string arg(argv[n]);
|
||||||
|
@ -1094,6 +1092,15 @@ inline void OptionParser::parse(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void OptionParser::reset()
|
||||||
|
{
|
||||||
|
unknown_options_.clear();
|
||||||
|
non_option_args_.clear();
|
||||||
|
for (auto& opt : options_)
|
||||||
|
opt->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline std::string OptionParser::help(const Attribute& max_attribute) const
|
inline std::string OptionParser::help(const Attribute& max_attribute) const
|
||||||
{
|
{
|
||||||
ConsoleOptionPrinter option_printer(this);
|
ConsoleOptionPrinter option_printer(this);
|
||||||
|
|
|
@ -49,13 +49,13 @@ void Config::init(const std::string& root_directory, const std::string& user, co
|
||||||
else if (getenv("HOME") == nullptr)
|
else if (getenv("HOME") == nullptr)
|
||||||
dir = "/var/lib/snapserver/";
|
dir = "/var/lib/snapserver/";
|
||||||
else
|
else
|
||||||
dir = getenv("HOME");
|
dir = string(getenv("HOME")) + "/.config/snapserver/";
|
||||||
|
|
||||||
if (!dir.empty() && (dir.back() != '/'))
|
if (!dir.empty() && (dir.back() != '/'))
|
||||||
dir += "/";
|
dir += "/";
|
||||||
|
|
||||||
if (dir.find("/var/lib/snapserver") == string::npos)
|
// if (dir.find("/var/lib/snapserver") == string::npos)
|
||||||
dir += ".config/snapserver/";
|
// dir += ".config/snapserver/";
|
||||||
|
|
||||||
int status = utils::file::mkdirRecursive(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
int status = utils::file::mkdirRecursive(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
if ((status != 0) && (errno != EEXIST))
|
if ((status != 0) && (errno != EEXIST))
|
||||||
|
|
|
@ -25,6 +25,16 @@
|
||||||
# in case there are a couple of longer running tasks, such as encoding
|
# in case there are a couple of longer running tasks, such as encoding
|
||||||
# multiple audio streams
|
# multiple audio streams
|
||||||
#threads = -1
|
#threads = -1
|
||||||
|
|
||||||
|
# the pid file when running as daemon
|
||||||
|
#pidfile = /var/run/snapserver/pid
|
||||||
|
|
||||||
|
# directory where persistent data is stored (server.json)
|
||||||
|
# if empty, data dir will be
|
||||||
|
# - "/var/lib/snapserver/" when running as daemon
|
||||||
|
# - "$HOME/.config/snapserver/" when not running as daemon
|
||||||
|
#datadir =
|
||||||
|
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -99,7 +109,7 @@
|
||||||
# note that you need to have the librespot binary on your machine
|
# note that you need to have the librespot binary on your machine
|
||||||
# sampleformat will be set to "44100:16:2"
|
# sampleformat will be set to "44100:16:2"
|
||||||
# file: file:///<path/to/PCM/file>?name=<name>
|
# file: file:///<path/to/PCM/file>?name=<name>
|
||||||
# process: process:///<path/to/process>?name=<name>[&wd_timeout=0][&log_stderr=false]
|
# process: process:///<path/to/process>?name=<name>[&wd_timeout=0][&log_stderr=false][¶ms=<process arguments>]
|
||||||
# airplay: airplay:///<path/to/airplay>?name=<name>[&port=5000]
|
# airplay: airplay:///<path/to/airplay>?name=<name>[&port=5000]
|
||||||
# note that you need to have the airplay binary on your machine
|
# note that you need to have the airplay binary on your machine
|
||||||
# sampleformat will be set to "44100:16:2"
|
# sampleformat will be set to "44100:16:2"
|
||||||
|
|
|
@ -75,21 +75,25 @@ int main(int argc, char* argv[])
|
||||||
&settings.logging.debug_logfile);
|
&settings.logging.debug_logfile);
|
||||||
|
|
||||||
// stream settings
|
// stream settings
|
||||||
conf.add<Value<size_t>>("p", "stream.port", "Server port", settings.stream.port, &settings.stream.port);
|
conf.add<Value<size_t>>("", "stream.port", "Server port", settings.stream.port, &settings.stream.port);
|
||||||
auto streamValue = conf.add<Value<string>>(
|
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,
|
"", "stream.stream", "URI of the PCM input stream.\nFormat: TYPE://host/path?name=NAME\n[&codec=CODEC]\n[&sampleformat=SAMPLEFORMAT]", pcmStream,
|
||||||
&pcmStream);
|
&pcmStream);
|
||||||
int num_threads = -1;
|
int num_threads = -1;
|
||||||
conf.add<Value<int>>("", "server.threads", "number of server threads", num_threads, &num_threads);
|
conf.add<Value<int>>("", "server.threads", "number of server threads", num_threads, &num_threads);
|
||||||
|
std::string pid_file = "/var/run/snapserver/pid";
|
||||||
|
conf.add<Value<string>>("", "server.pidfile", "pid file when running as daemon", pid_file, &pid_file);
|
||||||
|
std::string data_dir;
|
||||||
|
conf.add<Implicit<string>>("", "server.datadir", "directory where persistent data is stored", data_dir, &data_dir);
|
||||||
|
|
||||||
conf.add<Value<string>>("", "stream.sampleformat", "Default sample format", settings.stream.sampleFormat, &settings.stream.sampleFormat);
|
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|opus|pcm)[:options]\nType codec:? to get codec specific options",
|
conf.add<Value<string>>("", "stream.codec", "Default transport codec\n(flac|ogg|opus|pcm)[:options]\nType codec:? to get codec specific options",
|
||||||
settings.stream.codec, &settings.stream.codec);
|
settings.stream.codec, &settings.stream.codec);
|
||||||
// deprecated: stream_buffer, use chunk_ms instead
|
// deprecated: stream_buffer, use chunk_ms instead
|
||||||
conf.add<Value<size_t>>("", "stream.stream_buffer", "Default stream read chunk size [ms]", settings.stream.streamChunkMs,
|
conf.add<Value<size_t>>("", "stream.stream_buffer", "Default stream read chunk size [ms]", settings.stream.streamChunkMs,
|
||||||
&settings.stream.streamChunkMs);
|
&settings.stream.streamChunkMs);
|
||||||
conf.add<Value<size_t>>("", "stream.chunk_ms", "Default stream read chunk size [ms]", settings.stream.streamChunkMs, &settings.stream.streamChunkMs);
|
conf.add<Value<size_t>>("", "stream.chunk_ms", "Default stream read chunk size [ms]", settings.stream.streamChunkMs, &settings.stream.streamChunkMs);
|
||||||
conf.add<Value<int>>("b", "stream.buffer", "Buffer [ms]", settings.stream.bufferMs, &settings.stream.bufferMs);
|
conf.add<Value<int>>("", "stream.buffer", "Buffer [ms]", settings.stream.bufferMs, &settings.stream.bufferMs);
|
||||||
conf.add<Value<bool>>("", "stream.send_to_muted", "Send audio to muted clients", settings.stream.sendAudioToMutedClients,
|
conf.add<Value<bool>>("", "stream.send_to_muted", "Send audio to muted clients", settings.stream.sendAudioToMutedClients,
|
||||||
&settings.stream.sendAudioToMutedClients);
|
&settings.stream.sendAudioToMutedClients);
|
||||||
auto stream_bind_to_address = conf.add<Value<string>>("", "stream.bind_to_address", "address for the server to listen on",
|
auto stream_bind_to_address = conf.add<Value<string>>("", "stream.bind_to_address", "address for the server to listen on",
|
||||||
|
@ -108,12 +112,11 @@ int main(int argc, char* argv[])
|
||||||
auto tcp_bind_to_address = conf.add<Value<string>>("", "tcp.bind_to_address", "address for the server to listen on",
|
auto tcp_bind_to_address = conf.add<Value<string>>("", "tcp.bind_to_address", "address for the server to listen on",
|
||||||
settings.tcp.bind_to_address.front(), &settings.tcp.bind_to_address[0]);
|
settings.tcp.bind_to_address.front(), &settings.tcp.bind_to_address[0]);
|
||||||
|
|
||||||
// TODO: Should be possible to override settings on command line
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
op.parse(argc, argv);
|
op.parse(argc, argv);
|
||||||
conf.parse(config_file);
|
conf.parse(config_file);
|
||||||
|
conf.parse(argc, argv);
|
||||||
if (tcp_bind_to_address->is_set())
|
if (tcp_bind_to_address->is_set())
|
||||||
{
|
{
|
||||||
settings.tcp.bind_to_address.clear();
|
settings.tcp.bind_to_address.clear();
|
||||||
|
@ -219,9 +222,11 @@ int main(int argc, char* argv[])
|
||||||
if (user_group.size() > 1)
|
if (user_group.size() > 1)
|
||||||
group = user_group[1];
|
group = user_group[1];
|
||||||
}
|
}
|
||||||
|
if (data_dir.empty())
|
||||||
Config::instance().init("/var/lib/snapserver", user, group);
|
data_dir = "/var/lib/snapserver";
|
||||||
daemon.reset(new Daemon(user, group, "/var/run/snapserver/pid"));
|
Config::instance().init(data_dir, user, group);
|
||||||
|
daemon.reset(new Daemon(user, group, pid_file));
|
||||||
|
SLOG(NOTICE) << "daemonizing" << std::endl;
|
||||||
daemon->daemonize();
|
daemon->daemonize();
|
||||||
if (processPriority < -20)
|
if (processPriority < -20)
|
||||||
processPriority = -20;
|
processPriority = -20;
|
||||||
|
@ -232,7 +237,7 @@ int main(int argc, char* argv[])
|
||||||
SLOG(NOTICE) << "daemon started" << std::endl;
|
SLOG(NOTICE) << "daemon started" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Config::instance().init();
|
Config::instance().init(data_dir);
|
||||||
#else
|
#else
|
||||||
Config::instance().init();
|
Config::instance().init();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -94,6 +94,7 @@ void StreamServer::onChunkRead(const PcmStream* pcmStream, msg::PcmChunk* chunk,
|
||||||
{
|
{
|
||||||
// LOG(INFO) << "onChunkRead (" << pcmStream->getName() << "): " << duration << "ms\n";
|
// LOG(INFO) << "onChunkRead (" << pcmStream->getName() << "): " << duration << "ms\n";
|
||||||
bool isDefaultStream(pcmStream == streamManager_->getDefaultStream().get());
|
bool isDefaultStream(pcmStream == streamManager_->getDefaultStream().get());
|
||||||
|
// wrap it into a unique_ptr to ensure that the memory will be freed
|
||||||
unique_ptr<msg::PcmChunk> chunk_ptr(chunk);
|
unique_ptr<msg::PcmChunk> chunk_ptr(chunk);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void StreamUri::parse(const std::string& streamUri)
|
||||||
uri = uri.substr(0, this->uri.length() - 1);
|
uri = uri.substr(0, this->uri.length() - 1);
|
||||||
|
|
||||||
string decodedUri = strutils::uriDecode(uri);
|
string decodedUri = strutils::uriDecode(uri);
|
||||||
LOG(DEBUG) << "StreamUri: " << decodedUri << "\n";
|
LOG(DEBUG) << "StreamUri decoded: " << decodedUri << "\n";
|
||||||
|
|
||||||
string tmp(decodedUri);
|
string tmp(decodedUri);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue