Hello.
I’ve been looking into customizing my Linux environment more recently and I was curious if there were any options for playing sound effects when pressing keys on my keyboard. I couldn’t find any options I really trusted so I decided to make my own via python as it’s built into my Linux system. I got the code to work, technically. The issue is that when pressing many keys in a short timeframe, the sound has a small delay and when typing quickly over a short period of time the program outright crashes for some reason.
from pynput.keyboard import *
from playsound import playsound
def press_on(key):
print('press ON: {}'.format(key))
playsound("keyboard_click.mp3", block=False)
def press_off(key):
print('press OFF: {}'.format(key))
if key == Key.esc:
return False
with Listener(on_press = press_on, on_release = press_off) as listener:
listener.join()
print is just to visually see it recognizing my key strokes, and the text has no delay at all between key strokes and displaying to the console. Below is the output I get after the program crashes. This happened when running a typing test at about 80 words per minute. First the sound is very responsive, then it stops playing altogether, then after a couple of seconds the program crashes.
(python:66069): GStreamer-CRITICAL **: 15:14:32.456: gst_poll_get_read_gpollfd: assertion 'set != NULL' failed
press OFF: Key.backspace
press ON: Key.backspace
(python:66069): GStreamer-CRITICAL **: 15:14:32.580: gst_poll_get_read_gpollfd: assertion 'set != NULL' failed
(python:66069): GStreamer-CRITICAL **: 15:14:32.585: gst_poll_get_read_gpollfd: assertion 'set != NULL' failed
press OFF: Key.backspace
press ON: 's'
(python:66069): GStreamer-CRITICAL **: 15:14:32.732: gst_poll_get_read_gpollfd: assertion 'set != NULL' failed
Unhandled exception in listener callback
Traceback (most recent call last):
File "/usr/lib/python3.12/site-packages/pynput/_util/__init__.py", line 229, in inner
File "/usr/lib/python3.12/site-packages/pynput/_util/xorg.py", line 470, in _handler
File "/usr/lib/python3.12/site-packages/pynput/keyboard/_xorg.py", line 578, in _handle
File "/usr/lib/python3.12/site-packages/pynput/_util/__init__.py", line 145, in inner
File "/home/unknownvan/games/gamepart2/py/keytest.txt", line 6, in press_on
File "/usr/lib/python3.12/site-packages/playsound.py", line 180, in _playsoundNix
playsound.PlaysoundException: playbin.set_state returned <enum GST_STATE_CHANGE_FAILURE of type Gst.StateChangeReturn>
Traceback (most recent call last):
File "/home/unknownvan/games/gamepart2/py/keytest.txt", line 14, in <module>
listener.join()
File "/usr/lib/python3.12/site-packages/pynput/_util/__init__.py", line 281, in join
six.reraise(exc_type, exc_value, exc_traceback)
File "/usr/lib/python3.12/site-packages/six.py", line 718, in reraise
raise value.with_traceback(tb)
File "/usr/lib/python3.12/site-packages/pynput/_util/__init__.py", line 229, in inner
return f(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/pynput/_util/xorg.py", line 470, in _handler
self._handle(self._display_stop, event)
File "/usr/lib/python3.12/site-packages/pynput/keyboard/_xorg.py", line 578, in _handle
self.on_press(key)
File "/usr/lib/python3.12/site-packages/pynput/_util/__init__.py", line 145, in inner
if f(*args) is False:
^^^^^^^^
File "/home/unknownvan/games/gamepart2/py/keytest.txt", line 6, in press_on
playsound("keyboard_click.mp3", block=False)
File "/usr/lib/python3.12/site-packages/playsound.py", line 180, in _playsoundNix
raise PlaysoundException(
playsound.PlaysoundException: playbin.set_state returned <enum GST_STATE_CHANGE_FAILURE of type Gst.StateChangeReturn>
Maybe playsound isn’t the proper library to use in this situation? Or maybe I need to load the audio into memory some way instead of constantly reading from the file? I haven’t been able to figure out how to do that, though. Any help is appreciated.