gnu: mpd-service-type: Support configuration of outputs.

* gnu/services/audio.scm (<mpd-output>): New record type.
(<mpd-configuration>)[outputs]: New field.
(mpd-output, mpd-output?, mpd-output->string): New procedures.
(mpd-config->file): Use mpd-output->string.
* doc/guix.texi (Audio Services): Document mpd-output fields.
This commit is contained in:
Ricardo Wurmus 2019-10-29 15:07:25 +01:00
parent 7ff157c16c
commit 878e0e1bb0
No known key found for this signature in database
GPG key ID: 197A5888235FACAC
2 changed files with 128 additions and 17 deletions

View file

@ -22394,9 +22394,69 @@ The port to run mpd on.
The address that mpd will bind to. To use a Unix domain socket,
an absolute path can be specified here.
@item @code{outputs} (default: @code{"(list (mpd-output))"})
The audio outputs that MPD can use. By default this is a single output using pulseaudio.
@end table
@end deftp
@deftp {Data Type} mpd-output
Data type representing an @command{mpd} audio output.
@table @asis
@item @code{name} (default: @code{"MPD"})
The name of the audio output.
@item @code{type} (default: @code{"pulse"})
The type of audio output.
@item @code{enabled?} (default: @code{#t})
Specifies whether this audio output is enabled when MPD is started. By
default, all audio outputs are enabled. This is just the default
setting when there is no state file; with a state file, the previous
state is restored.
@item @code{tags?} (default: @code{#t})
If set to @code{#f}, then MPD will not send tags to this output. This
is only useful for output plugins that can receive tags, for example the
@code{httpd} output plugin.
@item @code{always-on?} (default: @code{#f})
If set to @code{#t}, then MPD attempts to keep this audio output always
open. This may be useful for streaming servers, when you dont want to
disconnect all listeners even when playback is accidentally stopped.
@item @code{mixer-type}
This field accepts a symbol that specifies which mixer should be used
for this audio output: the @code{hardware} mixer, the @code{software}
mixer, the @code{null} mixer (allows setting the volume, but with no
effect; this can be used as a trick to implement an external mixer
External Mixer) or no mixer (@code{none}).
@item @code{extra-options} (default: @code{'()"})
An association list of option symbols to string values to be appended to
the audio output configuration.
@end table
@end deftp
The following example shows a configuration of @code{mpd} that provides
an HTTP audio streaming output.
@lisp
(service mpd-service-type
(mpd-configuration
(outputs
(list (mpd-output
(name "streaming")
(type "httpd")
(mixer-type 'null)
(extra-options
`((encoder . "vorbis")
(port . "8080"))))))))
@end lisp
@node Virtualization Services
@subsection Virtualization services

View file

@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@ -23,7 +24,9 @@ (define-module (gnu services audio)
#:use-module (gnu packages mpd)
#:use-module (guix records)
#:use-module (ice-9 match)
#:export (mpd-configuration
#:export (mpd-output
mpd-output?
mpd-configuration
mpd-configuration?
mpd-service-type))
@ -33,6 +36,25 @@ (define-module (gnu services audio)
;;;
;;; Code:
(define-record-type* <mpd-output>
mpd-output make-mpd-output
mpd-output?
(type mpd-output-type
(default "pulse"))
(name mpd-output-name
(default "MPD"))
(enabled? mpd-output-enabled?
(default #t))
(tags? mpd-output-tags?
(default #t))
(always-on? mpd-output-always-on?
(default #f))
(mixer-type mpd-output-mixer-type
;; valid: hardware, software, null, none
(default #f))
(extra-options mpd-output-extra-options
(default '())))
(define-record-type* <mpd-configuration>
mpd-configuration make-mpd-configuration
mpd-configuration?
@ -51,27 +73,56 @@ (define-record-type* <mpd-configuration>
(port mpd-configuration-port
(default "6600"))
(address mpd-configuration-address
(default "any")))
(default "any"))
(outputs mpd-configuration-outputs
(default (list (mpd-output)))))
(define (mpd-output->string output)
"Convert the OUTPUT of type <mpd-output> to a configuration file snippet."
(let ((extra (string-join
(map (match-lambda
((key . value)
(format #f " ~a \"~a\""
(string-map
(lambda (c) (if (char=? c #\-) #\_ c))
(symbol->string key))
value)))
(mpd-output-extra-options output))
"\n")))
(format #f "\
audio_output {
type \"~a\"
name \"~a\"
~:[ enabled \"no\"~%~;~]\
~:[ tags \"no\"~%~;~]\
~:[~; always_on \"yes\"~%~]\
~@[ mixer_type \"~a\"~%~]\
~a~%}~%"
(mpd-output-type output)
(mpd-output-name output)
(mpd-output-enabled? output)
(mpd-output-tags? output)
(mpd-output-always-on? output)
(mpd-output-mixer-type output)
extra)))
(define (mpd-config->file config)
(apply
mixed-text-file "mpd.conf"
"audio_output {\n"
" type \"pulse\"\n"
" name \"MPD\"\n"
"}\n"
"pid_file \"" (mpd-file-name config "pid") "\"\n"
(map (match-lambda
((config-name config-val)
(string-append config-name " \"" (config-val config) "\"\n")))
`(("user" ,mpd-configuration-user)
("music_directory" ,mpd-configuration-music-dir)
("playlist_directory" ,mpd-configuration-playlist-dir)
("db_file" ,mpd-configuration-db-file)
("state_file" ,mpd-configuration-state-file)
("sticker_file" ,mpd-configuration-sticker-file)
("port" ,mpd-configuration-port)
("bind_to_address" ,mpd-configuration-address)))))
(append (map mpd-output->string
(mpd-configuration-outputs config))
(map (match-lambda
((config-name config-val)
(string-append config-name " \"" (config-val config) "\"\n")))
`(("user" ,mpd-configuration-user)
("music_directory" ,mpd-configuration-music-dir)
("playlist_directory" ,mpd-configuration-playlist-dir)
("db_file" ,mpd-configuration-db-file)
("state_file" ,mpd-configuration-state-file)
("sticker_file" ,mpd-configuration-sticker-file)
("port" ,mpd-configuration-port)
("bind_to_address" ,mpd-configuration-address))))))
(define (mpd-file-name config file)
"Return a path in /var/run/mpd/ that is writable