After weeks of struggling how to setup PulseAudio properly on a server for concurrent audio sources I finally found a way. This is a little guide through the process.
In my living room there is a little server machine for a lot of purposes. For example, it is connected to my A/V receiver (and obviously a TV) so I can use this machine for playing audio and video. My setup is the following:
- Kodi for playing movies, series, and live TV (over DVB-T2)
- Music Player Daemon (MPD) for playing music
Last but not least, I like to play audio from my other devices which use a TCP/IP connection to this machine over WiFi.
This doesn't look like a complicated setup if you have profund knowledge in GNU/Linux administration, right? For the audio part this sounds like a perfect job for PulseAudio which runs in the background. But it has many caveats, for example:
- Play video and audio through HDMI
- Play audio from several sources at once
- Start automatically at boot
PulseAudio has a system mode which supports multiple audio sources, but this is a bad idea. So we need to find another way.
Currently, the operating system is a Ubuntu Server 16.04 LTS, but this should work with newer versions or other GNU/Linux distributions as well.
Kodi, MPD and PulseAudio are already installed via apt
. Kodi has its own package repository for the latest versions.
(By the way, I mentioned live TV: This job is done by TVHeadend. I had to install a nightly build because of DVB-T2 which comes with a HVEC. But this is a different story…)
All steps are done via SSH because it is a headless setup with no grafical interface (except Kodi). So connect to your machine before we tcontinue:
ssh myserver
If we need super-user rights (root
) we gain it with sudo
.
First we need to know the right audio sink for HDMI. pacmdb
can find it for us:
pacmd list-sinks
For me, the mainboard has two (analog and digital) and the second is the right one: alsa_output.hw_0_8
.
PulseAudio has several configuration files you can find under /etc/pulse/
. Edit the default configuration file /etc/pulse/default.pa
:
sudo nano /etc/pulse/default.pa
Set the default sink and allow everyone in the (trusted) network to stream audio to PulseAudio. By default, PulseAudio uses Unix socket which does not allow remote access. Almost everything is commented-out so I add my stuff at the end of the file:
set-default-sink alsa_output.hw_0_8
load-module module-native-protocol-tcp auth-anonymous=1
Next we edit the client configuration file /etc/pulse/client.conf
which will be used by Kodi, MPD & Co.:
sudo nano /etc/pulse/client.conf
This tells the clients to use a TCP connection, use HDMI by default and autospawn the PulseAudio process:
default-server = 127.0.0.1
default-sink = alsa_output.hw_0_8
autospawn = yes
In the daemon configuration file /etc/pulse/daemon.pa
we tell PulseAudio to never sleep. This prevents hickups:
exit-idle-time = -1
As mentioned before we should not run PulseAudio in system mode with super-user rights (root
). So every user should be allowed to access PulseAudio. We need to add them to the groups audio
, pulse
, and pulse-access
. PulseAudio, Kodi and MPD bring their own users so we take of them as well:
sudo usermod -aG audio,pulse,pulse-access `whoami`
sudo usermod -aG audio,pulse,pulse-access pulse
sudo usermod -aG audio,pulse,pulse-access kodi
sudo usermod -aG audio,pulse,pulse-access mpd
Log out and re-login to make sure the new group settings take effect.
logout # or: [CTRL]+D
ssh myserver
PulseAudio should automatically start at boot without any user interaction and just right before Kodi and MPD start. Ubuntu and many other distributions use systemd to boot the user space. Therefore, we need a systemd unit for PulseAudio. Create a new file at /etc/systemd/system/pulseaudio.service
and edit it:
sudo nano /etc/systemd/system/pulseaudio.service
Put these lines into that file:
[Unit]
Description=Pulseaudio sound server
After=avahi-daemon.service network.target
[Service]
Type=forking
User=pulse
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /var/run/pulse/.config/pulse
ExecStartPre=-/bin/chown pulse:pulse -R /var/run/pulse/
ExecStart=/usr/bin/pulseaudio \
--realtime \
--no-cpu-limit \
--disallow-exit \
--daemonize \
--log-target=journal
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target kodi.service mpd.service
This tells systemd to start PulseAudio with the user pulse
in daemon mode. PulseAudio will grab all resources it needs and log right into the systemd journal. If PulseAudio fails at any time it will be restarted. In the last line you can see PulseAudio must be started before Kodi and MPD.
We need a clean state so start PulseAudio:
pulseaudio -k
Tell systemd to enable the new unit and start it:
sudo systemctl enable pulseaudio.service
sudo systemctl start pulseaudio.service
If you want to know whether PulseAudio is running use ps
:
ps -eF | grep pulse
Another way is to use systemctl
:
sudo systemctl status pulseaudio.service
Check the journal in a parallel SSH session:
sudo journalctl -fn 1000 -u pulseaudio
Now it's time for a first test. Play a audio file with mplayer
(or something else). PulseAudio just uses Alsa to access the audio devices. Alsa is already installed on the system and is shipped with some WAVE files we can use for our tests:
mplayer -ao pulse /usr/share/sounds/alsa/Front_Right.wav
Can you hear something? Yes? Excellent?
No? Okay, don't panic. Something went wrong. Maybe the audio get lost on its way from your soundcard over your A/V receiver to your speakers.
For the Kodi part everything can be configured in the grafical interface. In version 17 go to "Settings" -> "System" -> "Audio" and choose the right audio output device. For me, it's "Default, Default Output Device (PULSEAUDIO)". After that there is no need to restart Kodi.
Play a video to test the setup.
Now we need to configure MPD. Its main configuration file is located at /etc/mpd.conf
:
sudo nano /etc/mpd.conf
I skip most parts on how to configure MPD. There are many resources you may use. We concentrate on setting up the audio_output
:
audio_output {
type "pulse"
name "myserver PulseAudio"
}
Ignore the keys server
and sink
because the already create defaults in /etc/pulse/client.conf
.
Restart MPD:
sudo systemctl restart mpd.service
Use your favorite client to test it.
On my GNU/Linux laptop I play a sample file and directly send it to PulseAudio on my server machine:
PULSE_SERVER=myserver mplayer somefile.ogg
This guideline was not possible with the help of several resources: