MPD als Systemdienst mit ALSA und Pulseaudio

Aus DebianforumWiki
Zur Navigation springen Zur Suche springen
Wiki ‹ Multimedia und Spiele ‹ MPD als Systemdienst mit ALSA und Pulseaudio


Baustelle.png Baustelle: Dieser Artikel ist eine Baustelle. Das heißt, jemand hat sich dieses Artikels angenommen und überarbeitet ihn gerade.


Einführung

Im Netz gibt es nicht viel über die Aufgabenstellung, MPD (Musicplayer-Daemon) als Systemdienst mit laufendem Pulseaudio zu konfigurieren. Pulseaudio als Systemdienst laufen zu lassen ist gefährlich. Denn mit einer kleinen Unachtsamkeit kann man unbemerkt die Ausgabe des Mikrofons ins Internet streamen. Und jeder der die Adresse herausfindet, kann so alles hören, was gerade in dem Raum in dem der Rechner steht, gesprochen oder hörbar getan wird. Also wollen wir das gründlich vermeiden.

Das Problem mit Pulseaudio aber ist, dass es als User gestartet nur dann Töne von sich gibt, wenn ein User eingeloggt UND aktiv ist. Das schließt also aus, dass man ohne eingeloggtem User Musik hören kann. Zu diesem Zwecke aber müsste man noch zusätzlich MPD als der eigene User laufen lassen (was dem Prinzip des Servers ja gänzlich entgegenläuft, weshalb man ja MPD überhaupt nutzen möchte).

Läuft MPD unter der Nutzerkennung "mpd" ist wiederum eine Klangausgabe von MPD nicht möglich, wenn ein User eingeloggt ist, und Pulseaudio unter dieser Userkennung läuft, da Pulseaudio das Audio-Device exklusiv für sich beansprucht. Sind also zwei User eingeloggt, dann ist immer nur der Audioserver des gerade aktuell aktiven Users aktiv und gibt Klang aus.

Eine holprige Lösung gibt es noch, dass man die Streaming-Funktion von Pulseaudio nutzt und vom MPD als User mpd einen Stream zum eingeloggten und aktiven User über das lokale Netzwerk führt... aber auch hier ist es so, dass die Wiedergabe aufhört, sobald dieser User sich ausloggt.

Wie man es dreht und wendet, mit Pulseaudio kann man MPD nicht sinnvoll verwenden.

Nach längerem Studium habe ich dann eine praktikable Lösung gefunden.

Die Lösung im Überblick

MPD bekommt ein eigens Mixer-Device in Alsa. Und Pulseaudio gibt seine Klänge ebenfalls über ein "paralleles" Mixer-Device an Alsa über das dmix-Plugin aus. Und es bleibt einem frei zu entscheiden, ob Pulseaudio für die restlichen Programme mit Soundausgabe das default-Device sein soll oder nicht (also Ausgabe direkt über Alsa).

Programm --> Pulseaudio --> Alsa --> Hardware

Programm --> Alsa --> Hardware

MPD --> Alsa --> Hardware

Vorteile

Die Vorteile dieser Lösung sind folgende:

  • MPD kann als Systemdienst betrieben werden und spielt immer Musik ab, unabhängig davon ob ein User eingeloggt ist, oder ein Pulseaudio-Daemon läuft
  • Programme die nicht oder nur ungern mit Pulseaudio zusammenarbeiten können direkt über Alsa ihren Sound ausgeben
  • Alle Programme die Pulseaudio nutzen können auch dessen Features (Streaming, dynamische Änderung während der Ausgabe der Soundkarte) nutzen.

Nachteile

  • Die Lautstärke von MPD kann mit Pulseaudio nicht geregelt werden (alsamixer sind zusätzlich erforderlich)
  • MPD kann die Streamingfunktionen von Pulseaudio nicht nutzen.
  • Die Ausgabe von MPD ist auf die Soundkarten der Konfiguration festgelegt und kann nicht dynamisch wie mit Pulseaudio geändert werden.

Konkrete Konfiguration

Vorbereiten von Alsa

Zunächst einmal erstellen wir eine Datei »/etc/asound.conf«, in der wir Alsa so vorbereiten, dass sowohl MPD als auch Pulseaudio ein eigenes Mixer-Device bekommen.

######################################
## Default-Device
######################################
pcm.!default {
    type plug
    slave.pcm "duplex"  
	hint {
		show on
		description "Default Audio"
	}
}

#######################################
### Soundkarte: Onboard-Intel-Audio
#######################################

pcm.snd_card-intel {
        type hw
        card "Intel" 
        device 0
	channels 2
}

ctl.snd_card-intel {
        type hw
}


#######################################
### Dmixer
#######################################
#
pcm.dmixer {
    type dmix
    ipc_key 2024
    ipc_perm 0666
    slave {
	pcm "snd_card-intel"
        channels 2
    }
    bindings {
        0 0
        1 1
    }
}

ctl.dmixer {
  type hw
  card 0
}

#######################################
### Snooper
#######################################

pcm.dsnooper {
    type dsnoop
    ipc_key 2048
    ipc_perm 0666 
    slave.pcm "snd_card-intel"
    slave 
    {
        channels 2
    }
    bindings {
        0 0
        1 1
    }
}

pcm.duplex {
	type asym
	playback.pcm "dmixer"
	capture.pcm "dsnooper"
}

######################################
## eigene Kanäle für spezielle Software
######################################

### mpd-server ####
pcm.mpdvol {
	type softvol
	slave.pcm "duplex"
	control {
		name "MPD"
		card 0
	}
	hint {
		show on
		description "MPD-Mixer"
	}
}

ctl.mpdvol {
    type hw
    card "snd_card-intel"
} 

### PulseAudio ####
pcm.pvol {
	type softvol
	slave.pcm "duplex"
	control {
		name "PulseAudio"
		card 0
	}
	hint {
		show on
		description "PulseAudio-Mixer"
	}
}

ctl.pvol {
    type hw
    card "snd_card-intel"
} 


######################################
## DSP und OSS-Simulation
######################################

# DSP wird simuliert und benutzt das dmix-Plugin.
pcm.dsp0 {
    type plug
	slave.pcm "default"
}

# OSS-Steuerung für dsp0 (falls es benötigt wird...)
ctl.dsp0 {
    type plug
    slave.pcm "snd_card-intel"
}

# OSS-Steuerung für dsp0 (falls es benötigt wird...)
ctl.mixer0 {
    type plug
    slave.pcm "snd_card-intel"
}




Die Ausgabe von »aplay -L« liefert unter anderem so etwas

user@debian:~$ aplay -L
sysdefault:CARD=Intel
    HDA Intel, STAC9205 Analog
    Default Audio Device

Aufgrund dieser Ausgabe "CARD=Intel" ist in dieser Konfiguration bei "pcm.snd_card-intel" auch die Zeile

card "Intel" 

gewählt, damit die Zuordnung von der Nummerierung der Soundkarten durch den Kernel unabhängig und immer richtig ist.

Als Device stehen uns für MPD jetzt »mpdvol« mit dem Mixernamen »MPD« und

für Pulseaudio als sink »pvol« mit dem Mixernamen »PulseAudio« zur Verfügung.

Als weitere Konfigurationsdatei muss geschaut werden, ob die Datei /usr/share/alsa/pulse-alsa.conf vorhanden ist. Wenn ja, dann kommentiert man am besten alle Zeile aus, damit die Datei dann so aussieht:


user@debian:~$ cat /usr/share/alsa/pulse-alsa.conf
# This file is referred to by /usr/share/alsa/pulse.conf to set pulseaudio as
# the default output plugin for applications using alsa when PulseAudio is
# running.

#pcm.!default {
#    type pulse
#    hint {
#        show on
#        description "Playback/recording through the PulseAudio sound server"
#    }
#}
#
#ctl.!default {
#    type pulse
#}

Kommentiert man den Inhalt nicht aus, verwenden ALLE Alsa-Programme Pulseaudio als Default-Ausgabegerät!! Hier musst du selber entscheiden, ob du das willst.

Weiters kann es noch zu Problemen kommen, dass das allgemeine dmix-Plugin die Ausgabe nur von einem User erlaubt. Solltest du also entweder Musik von MPD abspielen können ODER mit Pulseaudio und anderen Alsa-Anwendungen, dann ändere bitte folgendes:

In der Datei /etc/asound.conf ganz am Beginn die Zeile

defaults.pcm.ipc_perm 0666

einfügen. Dies gilt aber nur, wenn zum jetzigen Konfigurationszeitpunkt eine Fehlermeldung kommt, wenn mpd Musik abspielt und du z.B. mit speaker-test oder aplay einen Testsound abspielst.

Die Vorbereitung von Alsa ist soweit abgeschlossen. Nun zur Konfigruation von MPD:

Konfiguration von MPD

In der Datei /etc/mpd.conf erstellen wir ein Alsa-Output: Am besten fügst du folgendes Code-Schnippsel irgendwo direkt vor oder nach den bestehenden Outputs ein:

audio_output {
        type            "alsa"
        name            "MPD-ALSA"
        device          "mpdvol"
        mixer_control   "MPD"
        #format          "48000:16:2"   # optional
        enabled         "yes"
}

audio_output {
	type		"pulse"
	name		"MPD Pulse Output"
	server		"127.0.0.1"
}

Dabei kannst du die auskommentierte Zeile »format« an die Gegebenheiten deiner Soundkarte anpassen.

Jetzt startest du MPD neu, damit er die neue Konfiguration und auch die neue Alsa-Konfiguration einliest und verwendet.

systemctl restart mpd.service

oder

invoke-rc.d mpd restart

(je nachdem ob du initv oder systemd installiert hast)

In deinem MPD-Client musst du noch das richtige Ausgabemodul wählen.

In meinem Fall habe ich mpc als CLI installiert und bekomme Auskunft über die zwei Outputs

user@debian:~$ mpc outputs
Output 1 (MPD-ALSA) is enabled
Output 2 (MPD Pulse Output) is disabled


Um nun »MPD-ALSA« einzuschalten macht man

user@debian:~$ mpc enable 1

da es hier Output 1 ist (siehe Ausgabe vorhin)


Du solltest jetzt im Alsamixer (ich empfehle qasmixer) einen neuen Regler "MPD" sehen, mit dem du die Lautstärke von MPD unabhängig vom Rest steuern kannst. Wenn du in einem MPD-Client die Lautstärke veränderst, müsste nun auch dieser Regler rauf- oder runtergehen.

Es gibt auch noch einen zweiten Output, nämlich für Pulseaudio. Damit kannst du MPD auch auf deinen lokalen Pulseaudio ausgeben lassen und damit dann die Streaming-Funktionen von Pulseaudio nutzen. Allerdings mit den Einschränkungen aus der Einleitung dieses Artikels.

Nun zu Pulseaudio

Konfiguration von Pulseaudio

Damit Pulseaudio nur dann gestartet wird (und auch gleich wieder beendet), wenn eine Anwendung darauf zugreift, ist folgende Konfiguration notwendig: In /etc/pulse/client.conf wird folgende Zeile auskommentiert:

 autospawn = yes

In /etc/pulse/daemon.conf sind das die einzigen unkommentierten Zeilen

 exit-idle-time = 0
 flat-volumes = yes

Und die Datei /etc/pulse/default.pa nennst du am besten in /etc/pulse/default.pa.orig um

root@debian:~# cp /etc/pulse/default.pa /etc/pulse/default.pa.orig

Dann erstellst du eine neue Datei /etc/pulse/default.pa mit folgendem Inhalt

root@debian:~# editor /etc/pulse/default.pa
## from:
## <https://wiki.archlinux.org/index.php/PulseAudio/Examples#PulseAudio_as_a_minimal_unintrusive_dumb_pipe_to_ALSA>
## and <https://wiki.debianforum.de/wiki/?title=MPD_als_Systemdienst_mit_ALSA_und_Pulseaudio>
# Replace the *entire* content of this file with these few lines and
# read the comments
.fail
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore

### Automatically augment property information from .desktop files
### stored in /usr/share/application
load-module module-augment-properties

### Should be after module-*-restore but before module-*-detect
load-module module-switch-on-port-available


    # Set tsched=0 here if you experience glitchy playback. This will
    # revert back to interrupt-based scheduling and should fix it.
    #
    # Replace the device= part if you want pulse to use a specific device
    # such as "dmix" and "dsnoop" so it doesn't lock an hw: device.
    
    # INPUT/RECORD
    load-module module-alsa-source device="pvol" tsched=1
    
    # OUTPUT/PLAYBACK
    load-module module-alsa-sink device="pvol" tsched=1 
    
### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect
.else
### Use the static hardware detection module (for systems that lack udev support)
load-module module-detect

### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle

### Enable positioned event sounds
load-module module-position-event-sounds


load-module module-filter-heuristics
load-module module-filter-apply
.endif

### Automatically load driver modules for Bluetooth hardware
.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif

.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif

    # Accept clients -- very important
    load-module module-native-protocol-unix 
    load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1

.nofail
.ifexists module-x11-publish.so
    # Publish to X11 so the clients know how to connect to Pulse. Will
    # clear itself on unload.
    load-module module-x11-publish
.endif

### Automatically move streams to the default sink if the sink they are
### connected to dies, similar for sources
load-module module-rescue-streams

### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink

### Honour intended role device property
load-module module-intended-roles

### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle

### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
.ifexists module-console-kit.so
load-module module-console-kit
.endif
.ifexists module-systemd-login.so
load-module module-systemd-login
.endif

### Cork music/video streams when a phone stream is active
load-module module-role-cork

Wie du unschwer erkennen kannst, ist hier auch die Quelle genannt, wo ich die Anregung zu dieser Konfiguration gefunden habe ;-) Mit dieser default.pa hast du für Pulseaudio nach wie vor die automatische Erkennung von zusätzlich an- und abgesteckter Sound-Hardware und sonstigen Komfort, aber Pulseaudio gibt über pvol Sound aus und bekommt Input ebenfalls über pvol. (Also z.B. vom Internen Mikrofon, um in einem Telefonieprogramm auch Sprechen zu können).

Wenn du pulseaudio nun neu startest

user@debian:~$ pulseaudio -k

(Das beendet einen allfällig laufenden Audioserver, Das Öffnen eines Audio- oder Videoprogramms und wählen von »PulseAudio-Mixer« als Ausgabe-Gerät startet den Server neu), müsste im Alsamixer nun auch der Schieberegler »PulseAudio« zu finden sein.

Gutes Gelingen und Hörgenuss