I want to run pygame mixer inside systemd, i used this code as an example:
from pygame import mixer
import signal,sys,time
def signal_handler(signal,frame):
global inter
inter=True
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
def play_audio_file(fname):
if mixer.get_init() != None:
mixer.quit()
mixer.init()
mixer.Sound(fname).play()
while True:
play_audio_file('/home/mohammad/tmp/ding.wav')
time.sleep(0.5)
and the following systemd service file:
[Unit]
Description=pygame mixer test
Wants=network-online.target
After=network-online.target
[Service]
Environment=VIRTUAL_ENV=/home/mohammad/env
Environment=PATH=/home/mohammad/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/bin/python /home/mohammad/tmp/service.py
WorkingDirectory=/home/mohammad/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=mohammad
[Install]
WantedBy=multi-user.target
When I start the service without other programs the script works as expected (the wav file play repeatedly) but when I start a program that output sound and then start the service I get this error:
Mar 02 01:12:04 mohammad-pc python[3415]: ALSA lib pcm_dmix.c:1099:(snd_pcm_dmix_open) unable to open slave Mar 02 01:12:04 mohammad-pc python[3415]: Traceback (most recent call last): Mar 02 01:12:04 mohammad-pc python[3415]: File "/home/mohammad/tmp/service.py", line 20, in Mar 02 01:12:04 mohammad-pc python[3415]:
play_audio_file('/home/mohammad/tmp/ding.wav') Mar 02 01:12:04 mohammad-pc python[3415]: File "/home/mohammad/tmp/service.py", line 14, in play_audio_file Mar 02 01:12:04 mohammad-pc python[3415]:
mixer.init() Mar 02 01:12:04 mohammad-pc python[3415]: pygame.error: No available audio device
This problem only appears on my manjaro linux machine running pulseaudio, but when I run the same code in my raspberrypi(raspbian strech) which runs alsa only without pulseaudio then the problem is resolved.
I was able to solve the problem (on my manjaro machine of course) by passing the DISPLAY and Home environment variable inside the service file like so:
[Unit]
Description=pygame mixer test
Wants=network-online.target
After=network-online.target
[Service]
Environment=VIRTUAL_ENV=/home/mohammad/env
Environment=PATH=/home/mohammad/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/usr/bin/python /home/mohammad/tmp/service.py
Environment=DISPLAY=:0
Environment=HOME=/home/mohammad
WorkingDirectory=/home/mohammad/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=mohammad
[Install]
WantedBy=multi-user.target
But I want to understand why would pygame needs these variables and can this be avoided ?
UPDATE 1:
when I included pygame in my main project(other than the example code above) I also needed to include Environment=XDG_RUNTIME_DIR=/run/user/1000
for it to work properly