2

I'm trying to run an audio visualization python script on my raspberry pi over SSH. The script uses pyaudio for the microphone input, which I understand uses pulseaudio under the hood. The script is also using an Adafruit library to control some NeoPixel LEDs, which must be run as root.

I've learned that by default pulseaudio doesn't run as root, but must run as a user. I verified this by creating a simple python script (throughput.py) to list the pyaudio devices. When I run without sudo I see 3 devices, including pulse:

pi@raspberrypi:~/audio-reactive-led-strip/python $ python3 throughput.py

Input Device id  1  -  Antlion USB adapter: Audio (hw:1,0)
Input Device id  2  -  pulse
Input Device id  6  -  default

However, when I run it as sudo, I only see a single device and pulse is missing:

pi@raspberrypi:~/audio-reactive-led-strip/python $ sudo python3 throughput.py

Input Device id  1  -  Antlion USB adapter: Audio (hw:1,0)

Although it's apparently not recommended, I've modified /etc/systemd/system/pulseaudio.service following this post in order to run the pulseaudio service as system service. (It's not clear to me if this is the same as running it as root.):

[Unit]
Description=Pulseaudio sound server
After=avahi-daemon.service network.target

[Service]
ExecStart=/usr/bin/pulseaudio --system --disallow-exit --disallow-module-loading
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

With this in place, all 3 devices are listed when running as sudo (including pulse) and I'm able to run my visualization script locally on the pi.

However, if I SSH into the pi and run the exact same command (as sudo), it doesn't find the pulseaudio device - same as it was doing locally before I modified pulseaudio.service. My guess is there's slightly different permissions for sudo locally vs over SSH, but I'm pretty green at linux and haven't had much luck finding anything to suggest that's true or how to work around it.

I don't know if it's relevant, but I'm using a terminal inside VS Code Remote-SSH for the SSH parts.

UPDATE 1

Based on an answer below, I tried using Putty with X11 forwarding. However, I get the following error when running start-pulseaudio-x11:

pi@raspberrypi:~/audio-reactive-led-strip/python $ start-pulseaudio-x11
PuTTY X11 proxy: unable to connect to forwarded X server: Network error: Connection refused
xcb_connection_has_error() returned true
Failure: Module initialization failed
PuTTY X11 proxy: Unsupported authorisation protocol
xcb_connection_has_error() returned true
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused

Anyone know how to resolve this?

UPDATE 2

After copying the file .Xauthority from /home/pi to /root see this post, I was able to successfully see all 3 adapters when I run sudo python3 throughput.py from Putty with X11 forwarding enabled and Xming running!

However, it seems that this .Xauthority file is only good for one SSH session. I think I can copy it each time using sudo from Putty, but I haven't tried that yet. I'll have to read up on how the .Xauthority file works to try to understand what's going on and would definitely appreciate any insight people have!

4
  • With your systemd change to the pulseaudio.service file - what does the 'ps -aef' command show as the user for pulseaudio? I'm not sure what the '--system' flag does exaclty for pulseaudio, but you can explicitly set the user for a systemd service to root with the 'User=root' directive for the [Service] portion of the service file. As for SSH, you could set a root password, enable root ssh access ( raspberrypi.stackexchange.com/questions/48056/… -- if security is not huge deal / or just for development ), and run your script that way.
    – PhilBot
    Jan 11 at 13:09
  • Thanks for the help, @PhilBot! Looks like pulseaudio is indeed running at as user pi and not as root. I'll try the changes you suggested next
    – rkor
    Jan 12 at 4:24
  • After adding User=root to pulseaudio.service, pulseaudio is still running as pi. What's interesting is that this isn't a problem when I run my python script locally.
    – rkor
    Jan 12 at 4:48
  • I enabled the root account over SSH, the pulseaudio device is still missing when I run the python script.
    – rkor
    Jan 12 at 5:07
1

I ran into the exact same problem using Adafruit library to control NeoPixel LEDs and pulseaudio to record audio data with python. Everything worked fine locally, but outputed the following error code when trying to run the script over SSH:

XDG_RUNTIME_DIR (/run/user/1000) is not owned by us
(uid 0), but by uid 1000! (This could e g happen if
you try to connect to a non-root PulseAudio as a
root user, over the native protocol. Don't do that.)

On my search I stumbled over the following command

start-pulseaudio-x11

which solved my issue (I already had X11 forwarding activated on the RasPi and my PuTTY SSH sessions to display file dialogs).

2
  • Is start-pulseaudio-x11 supposed to be run on the locally pi or the in the remotely on Putty? I tried enabling the X11 forwarding, but get this error: (audioviz) pi@raspberrypi:~/audio-reactive-led-strip/python $ start-pulseaudio-x11 PuTTY X11 proxy: unable to connect to forwarded X server: Network error: Connection refused xcb_connection_has_error() returned true Failure: Module initialization failed
    – rkor
    Apr 19 at 2:19
  • Sorry, I'm rereading your answer and realize you said you had already setup X11 forwarding on the pi. I'm guessing that's the source of my issue. I'll see if I can figure that out.
    – rkor
    Apr 19 at 2:31
0

The proper approach is probably finding out the device node of the LED and use setfacl to grant a user permission to manipulate it.

2
  • Could you elaborate on this? It seem like this would save some headaches for a lot of people who use the Adafruit library.
    – rkor
    Apr 19 at 2:28
  • Well, it's just like chmod/chown but instead of changing permission/ownership setfacl "adds" instead. It doesn't have anything to do with the library. I don't know what's the device node of the LEDs or if that's how the library access it though, but take a disk as an example, you can do something like setfacl -m u:tom:rw /dev/sda with sudo/root, then you don't need either of those to read/write the disk (with e.g. dd or qemu) on block level. Always read the man pages for further details. Note that permission/ownership/ACL of device nodes are volatile.
    – Tom Yan
    Apr 19 at 5:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.