hilbert / hilbert-docker-images

Application with a dynamic choice of docker containers to run
Apache License 2.0
22 stars 8 forks source link

Pulseaudio support #15

Closed porst17 closed 8 years ago

porst17 commented 8 years ago

I made some tests regarding PulseAudio. In the following, I am assuming pulseaudio is running on the host for the current user:

docker run -ti --rm -v /run/user/$UID/pulse/native:/run/user/$UID/pulse/native \
    -v ~/.config/pulse/cookie:/run/pulse/cookie \
    -e PULSE_SERVER=/run/user/$UID/pulse/native \
    -e PULSE_COOKIE=/run/pulse/cookie \
    phusion/baseimage \
    /bin/bash -c "apt-get update && apt-get install -yy pulseaudio && "`
        `"curl http://www.kozco.com/tech/piano2.wav | pacat"

This should play some piano music. The -v paths in the container are kind of arbitrary. I did not change any settings on my Ubuntu 14.04 host. Pulseaudio runs in user mode on the host, which is accessed by root in the container (the socket is rw for anyone; authentication happens via the cookie). It is also possible to run pulseaudio clients as a non-privilidged user inside the container. But the user inside the container needs access to the cookie file (via chmod or by copying the file into the container instead of mounting it). It’s also possible to disable authentication altogether by passing auth-cookie-enabled=0 to the pulseaudio module module-native-protocol-unix. It looks like this can be done via ~/.config/pulse/default.pa (copied from /etc/pulse/default.pa):

load-module module-native-protocol-unix auth-cookie-enabled=0

I did not test this, though, but I think, disabling authentication should be considered bad practice anyway and we should avoid it if possible (and forwarding the authentication cookie into the container is not a big deal).

I would be great to test this setup and if the sound/mixing problems are gone afterwards.

malex984 commented 8 years ago

Thanks, this works! I changed :kivy to make use of it:

cd kivy
make pull
make check

NOTE: for now make check assumes that the current user has pulseaudio server (standard setup) running.

porst17 commented 8 years ago

I found out how it is possible to let pulseaudio make use of shared memory:

docker run -ti --rm -v /run/user/$UID/pulse/native:/run/user/$UID/pulse/native \
    -v ~/.config/pulse/cookie:/run/pulse/cookie \
    -v /dev/shm:/dev/shm \
    -e PULSE_SERVER=/run/user/$UID/pulse/native \
    -e PULSE_COOKIE=/run/pulse/cookie \
    phusion/baseimage \
    /bin/bash -c "apt-get update && apt-get install -yy pulseaudio && "`
        `"curl http://www.kozco.com/tech/piano2.wav | sudo -E -u \#$UID pacat"

Note the additional option -v /dev/shm:/dev/shm. It did not seem to be necessary to specify something like --ipc=host or --pid=host, but it was necessary to run the pulseaudio server and client with the same UID (hence, the sudo -E -u \#$UID pacat command to match the UID of the calling user).

Not sure how much more efficient the use of shared memory is instead of copying audio data over the socket, but I wanted to keep this here for reference.

porst17 commented 8 years ago

For some reason, my pulseaudio server now creates the socket under /tmp/pulse-..../native. I messed up my ~/.config/pulse configuration and had to delete this folder. Not sure if this is connected. Anyway, the above approach with /run/user/$UID/pulse/native does not work anymore. The path has to be extracted dynamically. There are several ways to get the server:

In a final implementation, the dynamically changing paths have to be take into account.