mk-fg / python-pulse-control

Python high-level interface and ctypes-based bindings for PulseAudio (libpulse)
https://pypi.org/project/pulsectl/
MIT License
170 stars 36 forks source link

pulse.close() not working #71

Closed RESP3CT88 closed 2 years ago

RESP3CT88 commented 2 years ago

When I run pulse.close() it is not stopping the execution of pulse.play_sample(). The sample still continues to play....

class AudioTestPlay(QObject):

    def __init__(self):
        super().__init__()
        self.pulse = pulsectl.Pulse()

    def play(self):
        self.pulse.play_sample('starwars')

    def stop(self):
        self.pulse.close()
mk-fg commented 2 years ago

Hm, I think it might be the expected behavior and what this functionality is actually for - stuff like notification sounds from apps and scripts, which might exit immediately after signaling pulse to play it, e.g. if it's an error. That's pulseaudio itself playing the sample sound that it has loaded of course, not your application sending it sound stream data, you only start the process from the app/script.

One workaround that comes to mind might be to mute the stream before exiting, as pretty sure pulse should expose those, probably linked to an initiating app somehow, likely looking mostly like its audio stream.

RESP3CT88 commented 2 years ago

I added mute() before close(), but it still doesn't stop the sample. The sample gets muted, but it continues to play.

class AudioTestPlay(QObject):

    def __init__(self):
        super().__init__()
        self.pulse = pulsectl.Pulse()

    def play(self):
        self.pulse.play_sample('starwars')

    def stop(self):
        self.pulse.mute(self.pulse.sink_list()[0])
        self.pulse.close()

Maybe I will use "paplay" command, instead.

mk-fg commented 2 years ago

Maybe setting mute on the wrong sink then? I mean, if muting sink doesn't affect samples, it sounds like a bug in pulse, definitely should work with the right sink.

Also, I meant muting specific sample-playback stream, which you can match either by props that pulse creates it with or even pass custom proplist to match it by.

There's also API to kill clients and streams in pulseaudio, but don't think it's wrapped here atm, and should work roughly same as mute anyway, if sample is short enough.

mk-fg commented 2 years ago

Maybe I will use "paplay" command, instead.

For sounds that pulseaudio sample-cache API is not designed for, definitely sounds like a better idea.

There's no playback functionality in this module, and it'll kinda suck with slow python and module's blocking operation mode anyway, so yeah, paplay would be my go-to for such task as well, at least for simple playback tasks where you don't need much control on-the-fly (otherwise I'd probably look at gstreamer).