nixos/snapserver: migrate to settings option (#441245)
This commit is contained in:
@@ -162,6 +162,8 @@
|
|||||||
|
|
||||||
- The `yeahwm` package and `services.xserver.windowManager.yeahwm` module were removed due to the package being broken and unmaintained upstream.
|
- The `yeahwm` package and `services.xserver.windowManager.yeahwm` module were removed due to the package being broken and unmaintained upstream.
|
||||||
|
|
||||||
|
- The `services.snapserver` module has been migrated to use the settings option and render a configuration file instead of passing every option over the command line.
|
||||||
|
|
||||||
- The `services.postgresql` module now sets up a systemd unit `postgresql.target`. Depending on `postgresql.target` guarantees that postgres is in read-write mode and initial/ensure scripts were executed. Depending on `postgresql.service` only guarantees a read-only connection.
|
- The `services.postgresql` module now sets up a systemd unit `postgresql.target`. Depending on `postgresql.target` guarantees that postgres is in read-write mode and initial/ensure scripts were executed. Depending on `postgresql.service` only guarantees a read-only connection.
|
||||||
|
|
||||||
- The `services.siproxd` module has been removed as `siproxd` is unmaintained and broken with libosip 5.x.
|
- The `services.siproxd` module has been removed as `siproxd` is unmaintained and broken with libosip 5.x.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
options,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
@@ -9,77 +8,96 @@ let
|
|||||||
|
|
||||||
name = "snapserver";
|
name = "snapserver";
|
||||||
|
|
||||||
|
inherit (lib)
|
||||||
|
literalExpression
|
||||||
|
mkEnableOption
|
||||||
|
mkOption
|
||||||
|
mkPackageOption
|
||||||
|
mkRemovedOptionModule
|
||||||
|
mkRenamedOptionModule
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
cfg = config.services.snapserver;
|
cfg = config.services.snapserver;
|
||||||
|
|
||||||
# Using types.nullOr to inherit upstream defaults.
|
format = pkgs.formats.ini {
|
||||||
sampleFormat = lib.mkOption {
|
listsAsDuplicateKeys = true;
|
||||||
type = with lib.types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Default sample format.
|
|
||||||
'';
|
|
||||||
example = "48000:16:2";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
codec = lib.mkOption {
|
configFile = format.generate "snapserver.conf" cfg.settings;
|
||||||
type = with lib.types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Default audio compression method.
|
|
||||||
'';
|
|
||||||
example = "flac";
|
|
||||||
};
|
|
||||||
|
|
||||||
streamToOption =
|
|
||||||
name: opt:
|
|
||||||
let
|
|
||||||
os = val: lib.optionalString (val != null) "${val}";
|
|
||||||
os' = prefix: val: lib.optionalString (val != null) (prefix + "${val}");
|
|
||||||
toQueryString = key: value: "&${key}=${value}";
|
|
||||||
in
|
|
||||||
"--stream.stream=\"${opt.type}://"
|
|
||||||
+ os opt.location
|
|
||||||
+ "?"
|
|
||||||
+ os' "name=" name
|
|
||||||
+ os' "&sampleformat=" opt.sampleFormat
|
|
||||||
+ os' "&codec=" opt.codec
|
|
||||||
+ lib.concatStrings (lib.mapAttrsToList toQueryString opt.query)
|
|
||||||
+ "\"";
|
|
||||||
|
|
||||||
optionalNull = val: ret: lib.optional (val != null) ret;
|
|
||||||
|
|
||||||
optionString = lib.concatStringsSep " " (
|
|
||||||
lib.mapAttrsToList streamToOption cfg.streams
|
|
||||||
# global options
|
|
||||||
++ [ "--stream.bind_to_address=${cfg.listenAddress}" ]
|
|
||||||
++ [ "--stream.port=${toString cfg.port}" ]
|
|
||||||
++ optionalNull cfg.sampleFormat "--stream.sampleformat=${cfg.sampleFormat}"
|
|
||||||
++ optionalNull cfg.codec "--stream.codec=${cfg.codec}"
|
|
||||||
++ optionalNull cfg.streamBuffer "--stream.stream_buffer=${toString cfg.streamBuffer}"
|
|
||||||
++ optionalNull cfg.buffer "--stream.buffer=${toString cfg.buffer}"
|
|
||||||
++ lib.optional cfg.sendToMuted "--stream.send_to_muted"
|
|
||||||
# tcp json rpc
|
|
||||||
++ [ "--tcp.enabled=${toString cfg.tcp.enable}" ]
|
|
||||||
++ lib.optionals cfg.tcp.enable [
|
|
||||||
"--tcp.bind_to_address=${cfg.tcp.listenAddress}"
|
|
||||||
"--tcp.port=${toString cfg.tcp.port}"
|
|
||||||
]
|
|
||||||
# http json rpc
|
|
||||||
++ [ "--http.enabled=${toString cfg.http.enable}" ]
|
|
||||||
++ lib.optionals cfg.http.enable [
|
|
||||||
"--http.bind_to_address=${cfg.http.listenAddress}"
|
|
||||||
"--http.port=${toString cfg.http.port}"
|
|
||||||
]
|
|
||||||
++ lib.optional (cfg.http.docRoot != null) "--http.doc_root=\"${toString cfg.http.docRoot}\""
|
|
||||||
);
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(lib.mkRenamedOptionModule
|
(mkRenamedOptionModule
|
||||||
[ "services" "snapserver" "controlPort" ]
|
[ "services" "snapserver" "controlPort" ]
|
||||||
[ "services" "snapserver" "tcp" "port" ]
|
[ "services" "snapserver" "tcp" "port" ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "listenAddress" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "bind_to_address" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "port" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "port" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "sampleFormat" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "sampleformat" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "codec" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "codec" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "streamBuffer" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "chunk_ms" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "buffer" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "buffer" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "send" ]
|
||||||
|
[ "services" "snapserver" "settings" "stream" "chunk_ms" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "tcp" "enable" ]
|
||||||
|
[ "services" "snapserver" "settings" "tcp" "enabled" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "tcp" "listenAddress" ]
|
||||||
|
[ "services" "snapserver" "settings" "tcp" "bind_to_address" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "tcp" "port" ]
|
||||||
|
[ "services" "snapserver" "settings" "tcp" "port" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "http" "enable" ]
|
||||||
|
[ "services" "snapserver" "settings" "http" "enabled" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "http" "listenAddress" ]
|
||||||
|
[ "services" "snapserver" "settings" "http" "bind_to_address" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "http" "port" ]
|
||||||
|
[ "services" "snapserver" "settings" "http" "port" ]
|
||||||
|
)
|
||||||
|
(mkRenamedOptionModule
|
||||||
|
[ "services" "snapserver" "http" "docRoot" ]
|
||||||
|
[ "services" "snapserver" "settings" "http" "doc_root" ]
|
||||||
|
)
|
||||||
|
|
||||||
|
(mkRemovedOptionModule [
|
||||||
|
"services"
|
||||||
|
"snapserver"
|
||||||
|
"streams"
|
||||||
|
] "Configure `services.snapserver.settings.stream.source` instead")
|
||||||
];
|
];
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
@@ -88,31 +106,93 @@ in
|
|||||||
|
|
||||||
services.snapserver = {
|
services.snapserver = {
|
||||||
|
|
||||||
enable = lib.mkOption {
|
enable = mkEnableOption "snapserver";
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Whether to enable snapserver.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
package = lib.options.mkPackageOption pkgs "snapcast" { };
|
package = mkPackageOption pkgs "snapcast" { };
|
||||||
|
|
||||||
listenAddress = lib.mkOption {
|
settings = mkOption {
|
||||||
type = lib.types.str;
|
default = { };
|
||||||
default = "::";
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
description = ''
|
||||||
The address where snapclients can connect.
|
Snapserver configuration.
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
Refer to the [example configuration](https://github.com/badaix/snapcast/blob/develop/server/etc/snapserver.conf) for possible options.
|
||||||
type = lib.types.port;
|
|
||||||
default = 1704;
|
|
||||||
description = ''
|
|
||||||
The port that snapclients can connect to.
|
|
||||||
'';
|
'';
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = format.type;
|
||||||
|
options = {
|
||||||
|
stream = {
|
||||||
|
bind_to_address = mkOption {
|
||||||
|
default = "::";
|
||||||
|
description = ''
|
||||||
|
Address to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 1704;
|
||||||
|
description = ''
|
||||||
|
Port to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
source = mkOption {
|
||||||
|
type = with types; either str (listOf str);
|
||||||
|
example = "pipe:///tmp/snapfifo?name=default";
|
||||||
|
description = ''
|
||||||
|
One or multiple URIs to PCM inpuit streams.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
tcp = {
|
||||||
|
enabled = mkEnableOption "the TCP JSON-RPC";
|
||||||
|
|
||||||
|
bind_to_address = mkOption {
|
||||||
|
default = "::";
|
||||||
|
description = ''
|
||||||
|
Address to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 1705;
|
||||||
|
description = ''
|
||||||
|
Port to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
http = {
|
||||||
|
enabled = mkEnableOption "the HTTP JSON-RPC";
|
||||||
|
|
||||||
|
bind_to_address = mkOption {
|
||||||
|
default = "::";
|
||||||
|
description = ''
|
||||||
|
Address to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 1705;
|
||||||
|
description = ''
|
||||||
|
Port to listen on for snapclient connections.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
doc_root = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr path;
|
||||||
|
default = pkgs.snapweb;
|
||||||
|
defaultText = literalExpression "pkgs.snapweb";
|
||||||
|
description = ''
|
||||||
|
Path to serve from the HTTP servers root.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
openFirewall = lib.mkOption {
|
openFirewall = lib.mkOption {
|
||||||
@@ -122,200 +202,13 @@ in
|
|||||||
Whether to automatically open the specified ports in the firewall.
|
Whether to automatically open the specified ports in the firewall.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
inherit sampleFormat;
|
|
||||||
inherit codec;
|
|
||||||
|
|
||||||
streamBuffer = lib.mkOption {
|
|
||||||
type = with lib.types; nullOr int;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Stream read (input) buffer in ms.
|
|
||||||
'';
|
|
||||||
example = 20;
|
|
||||||
};
|
|
||||||
|
|
||||||
buffer = lib.mkOption {
|
|
||||||
type = with lib.types; nullOr int;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Network buffer in ms.
|
|
||||||
'';
|
|
||||||
example = 1000;
|
|
||||||
};
|
|
||||||
|
|
||||||
sendToMuted = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Send audio to muted clients.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
tcp.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to enable the JSON-RPC via TCP.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
tcp.listenAddress = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "::";
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
The address where the TCP JSON-RPC listens on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
tcp.port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 1705;
|
|
||||||
description = ''
|
|
||||||
The port where the TCP JSON-RPC listens on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
http.enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Whether to enable the JSON-RPC via HTTP.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
http.listenAddress = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "::";
|
|
||||||
example = "0.0.0.0";
|
|
||||||
description = ''
|
|
||||||
The address where the HTTP JSON-RPC listens on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
http.port = lib.mkOption {
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 1780;
|
|
||||||
description = ''
|
|
||||||
The port where the HTTP JSON-RPC listens on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
http.docRoot = lib.mkOption {
|
|
||||||
type = with lib.types; nullOr path;
|
|
||||||
default = pkgs.snapweb;
|
|
||||||
defaultText = lib.literalExpression "pkgs.snapweb";
|
|
||||||
description = ''
|
|
||||||
Path to serve from the HTTP servers root.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
streams = lib.mkOption {
|
|
||||||
type =
|
|
||||||
with lib.types;
|
|
||||||
attrsOf (submodule {
|
|
||||||
options = {
|
|
||||||
location = lib.mkOption {
|
|
||||||
type = lib.types.oneOf [
|
|
||||||
lib.types.path
|
|
||||||
lib.types.str
|
|
||||||
];
|
|
||||||
description = ''
|
|
||||||
For type `pipe` or `file`, the path to the pipe or file.
|
|
||||||
For type `librespot`, `airplay` or `process`, the path to the corresponding binary.
|
|
||||||
For type `tcp`, the `host:port` address to connect to or listen on.
|
|
||||||
For type `meta`, a list of stream names in the form `/one/two/...`. Don't forget the leading slash.
|
|
||||||
For type `alsa`, use an empty string.
|
|
||||||
'';
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
"/path/to/pipe"
|
|
||||||
"/path/to/librespot"
|
|
||||||
"192.168.1.2:4444"
|
|
||||||
"/MyTCP/Spotify/MyPipe"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
type = lib.mkOption {
|
|
||||||
type = lib.types.enum [
|
|
||||||
"pipe"
|
|
||||||
"librespot"
|
|
||||||
"airplay"
|
|
||||||
"file"
|
|
||||||
"process"
|
|
||||||
"tcp"
|
|
||||||
"alsa"
|
|
||||||
"spotify"
|
|
||||||
"meta"
|
|
||||||
];
|
|
||||||
default = "pipe";
|
|
||||||
description = ''
|
|
||||||
The type of input stream.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
query = lib.mkOption {
|
|
||||||
type = attrsOf str;
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Key-value pairs that convey additional parameters about a stream.
|
|
||||||
'';
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
# for type == "pipe":
|
|
||||||
{
|
|
||||||
mode = "create";
|
|
||||||
};
|
|
||||||
# for type == "process":
|
|
||||||
{
|
|
||||||
params = "--param1 --param2";
|
|
||||||
logStderr = "true";
|
|
||||||
};
|
|
||||||
# for type == "tcp":
|
|
||||||
{
|
|
||||||
mode = "client";
|
|
||||||
}
|
|
||||||
# for type == "alsa":
|
|
||||||
{
|
|
||||||
device = "hw:0,0";
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
inherit sampleFormat;
|
|
||||||
inherit codec;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = {
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
description = ''
|
|
||||||
The definition for an input source.
|
|
||||||
'';
|
|
||||||
example = lib.literalExpression ''
|
|
||||||
{
|
|
||||||
mpd = {
|
|
||||||
type = "pipe";
|
|
||||||
location = "/run/snapserver/mpd";
|
|
||||||
sampleFormat = "48000:16:2";
|
|
||||||
codec = "pcm";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
###### implementation
|
###### implementation
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.etc."snapserver.conf".source = configFile;
|
||||||
warnings =
|
|
||||||
# https://github.com/badaix/snapcast/blob/98ac8b2fb7305084376607b59173ce4097c620d8/server/streamreader/stream_manager.cpp#L85
|
|
||||||
lib.filter (w: w != "") (
|
|
||||||
lib.mapAttrsToList (
|
|
||||||
k: v:
|
|
||||||
lib.optionalString (v.type == "spotify") ''
|
|
||||||
services.snapserver.streams.${k}.type = "spotify" is deprecated, use services.snapserver.streams.${k}.type = "librespot" instead.
|
|
||||||
''
|
|
||||||
) cfg.streams
|
|
||||||
);
|
|
||||||
|
|
||||||
systemd.services.snapserver = {
|
systemd.services.snapserver = {
|
||||||
after = [
|
after = [
|
||||||
@@ -328,10 +221,13 @@ in
|
|||||||
"mpd.service"
|
"mpd.service"
|
||||||
"mopidy.service"
|
"mopidy.service"
|
||||||
];
|
];
|
||||||
|
restartTriggers = [ configFile ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
ExecStart = "${cfg.package}/bin/snapserver --daemon ${optionString}";
|
ExecStart = toString [
|
||||||
|
(lib.getExe' cfg.package "snapserver")
|
||||||
|
"--daemon"
|
||||||
|
];
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
LimitRTPRIO = 50;
|
LimitRTPRIO = 50;
|
||||||
LimitRTTIME = "infinity";
|
LimitRTTIME = "infinity";
|
||||||
@@ -349,9 +245,9 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts =
|
networking.firewall.allowedTCPPorts =
|
||||||
lib.optionals cfg.openFirewall [ cfg.port ]
|
lib.optionals cfg.openFirewall [ cfg.settings.stream.port ]
|
||||||
++ lib.optional (cfg.openFirewall && cfg.tcp.enable) cfg.tcp.port
|
++ lib.optional (cfg.openFirewall && cfg.settings.tcp.enabled) cfg.settings.tcp.port
|
||||||
++ lib.optional (cfg.openFirewall && cfg.http.enable) cfg.http.port;
|
++ lib.optional (cfg.openFirewall && cfg.settings.http.enabled) cfg.settings.http.port;
|
||||||
};
|
};
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
@@ -12,7 +13,7 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
name = "snapcast";
|
name = "snapcast";
|
||||||
meta = with pkgs.lib.maintainers; {
|
meta = with lib.maintainers; {
|
||||||
maintainers = [ hexa ];
|
maintainers = [ hexa ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -20,30 +21,27 @@ in
|
|||||||
server = {
|
server = {
|
||||||
services.snapserver = {
|
services.snapserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = port;
|
settings = {
|
||||||
tcp.port = tcpPort;
|
stream = {
|
||||||
http.port = httpPort;
|
port = port;
|
||||||
openFirewall = true;
|
source = [
|
||||||
buffer = bufferSize;
|
"pipe:///run/snapserver/mpd?name=mpd&mode=create"
|
||||||
streams = {
|
"pipe:///run/snapserver/bluetooth?name=bluetooth"
|
||||||
mpd = {
|
"tcp://127.0.0.1:${toString tcpStreamPort}?name=tcp"
|
||||||
type = "pipe";
|
"meta:///mpd/bluetooth/tcp?name=meta"
|
||||||
location = "/run/snapserver/mpd";
|
];
|
||||||
query.mode = "create";
|
buffer = bufferSize;
|
||||||
};
|
|
||||||
bluetooth = {
|
|
||||||
type = "pipe";
|
|
||||||
location = "/run/snapserver/bluetooth";
|
|
||||||
};
|
};
|
||||||
tcp = {
|
tcp = {
|
||||||
type = "tcp";
|
enabled = true;
|
||||||
location = "127.0.0.1:${toString tcpStreamPort}";
|
port = tcpPort;
|
||||||
};
|
};
|
||||||
meta = {
|
http = {
|
||||||
type = "meta";
|
enabled = true;
|
||||||
location = "/mpd/bluetooth/tcp";
|
port = httpPort;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
environment.systemPackages = [ pkgs.snapcast ];
|
environment.systemPackages = [ pkgs.snapcast ];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
asio,
|
asio,
|
||||||
avahi,
|
avahi,
|
||||||
boost,
|
boost,
|
||||||
|
expat,
|
||||||
flac,
|
flac,
|
||||||
libogg,
|
libogg,
|
||||||
libvorbis,
|
libvorbis,
|
||||||
@@ -23,13 +24,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "snapcast";
|
pname = "snapcast";
|
||||||
version = "0.30.0";
|
version = "0.32.3";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "badaix";
|
owner = "badaix";
|
||||||
repo = "snapcast";
|
repo = "snapcast";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-EJgpZz4PnXfge0rkVH1F7cah+i9AvDJVSUVqL7qChDM=";
|
hash = "sha256-pGON2Nh7GgcGvMUNI3nWstm5Q9R+VW9eEi4IE6KkFBo=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
@@ -42,6 +43,7 @@ stdenv.mkDerivation rec {
|
|||||||
boost
|
boost
|
||||||
asio
|
asio
|
||||||
avahi
|
avahi
|
||||||
|
expat
|
||||||
flac
|
flac
|
||||||
libogg
|
libogg
|
||||||
libvorbis
|
libvorbis
|
||||||
|
|||||||
Reference in New Issue
Block a user