Hi,
I am trying to launch a python systemd service that uses ALSA sound when the Raspberry Pi boots.
Here is the Talkie.service file in /etc/systemd/system:
Description=bondz-client
# Requires=sys-devices-platform-soc-soc:sound-sound-card1-controlC1.device
[Service]
User=user
Group=user
Type=simple
ExecStart=/usr/bin/python3 /home/romaing/Documents/Talkie_basic_sound_test.py
WorkingDirectory=/home/romaing/Documents/
StandardOutput=append:/var/log/bondz.log
StandardError=append:/var/log/bondz.log
[Install]
WantedBy=sound.target
If I start the service manually with systemctl
it works fine but upon boot I get this error in the logs (and systemd stops) Here’s the log file content :
2024-01-14 16:30:23,363 |Player| INFO:Device count = 0...
2024-01-14 16:30:23,364 |Player| INFO:Playing file tests/myrecording.wav...
2024-01-14 16:30:23,403 |Player| ERROR:Error playing tests/myrecording.wav
Traceback (most recent call last):
File "/home/romaing/Documents/Talkie_basic_sound_test.py", line 71, in playWaveFile
playStream = audio.open(
File "/usr/local/lib/python3.9/dist-packages/pyaudio/__init__.py", line 639, in open
stream = PyAudio.Stream(self, *args, **kwargs)
File "/usr/local/lib/python3.9/dist-packages/pyaudio/__init__.py", line 441, in __init__
self._stream = pa.open(**arguments)
OSError: [Errno -9996] Invalid output device (no default output device)
Here’s a simplified python code that loops a sound :
from Player import Player
import io
import wave
import logging
import traceback
import pyaudio
player = Player()
logger = logging.getLogger("Player")
audio = pyaudio.PyAudio()
logging.basicConfig(
format="%(asctime)s |%(name)s| %(levelname)s:%(message)s", level=logging.INFO
)
def play():
playWaveFile("tests/myrecording.wav", play)
def playWaveFile(filepath, callback):
# info = audio.get_default_output_device_info()
logger.info(f"Device count = {audio.get_device_count()}... ")
logger.info(f"Playing file {filepath}... ")
try:
wave_file = wave.open(filepath, "rb")
playStream = audio.open(
format=audio.get_format_from_width(wave_file.getsampwidth()),
channels=wave_file.getnchannels(),
rate=wave_file.getframerate(),
output=True,
)
data = wave_file.readframes(1024)
while data:
playStream.write(data)
data = wave_file.readframes(1024)
# Cleanup
playStream.stop_stream()
playStream.close()
logger.info(f"Playing {filepath} done.")
callback()
except Exception as e:
logger.error(f"Error playing {filepath} ")
traceback.print_exc()
# self._statusManager.set_app_status(Status.ERROR)
play()
I guess the sound card isn’t loaded when the service start but I thought sound.target would solve it, which it does not… Being a beginner on this topic, any help would be greatly appreciated.
I am running on Raspbian 11 (bullseye).
Here is the output of aplay -l
:
**** List of PLAYBACK Hardware Devices ****
card 0: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 [bcm2835-i2s-wm8960-hifi wm8960-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
Thank a lot for your help !