Skip to content

Commit

Permalink
Made the listener more robust to pulseaudio restarts
Browse files Browse the repository at this point in the history
Sometimes when I boot up my laptop, pulseaudio can't detect the devices
properly. I run `pulseaudio -k` to restart it, but this changes the
device ids and crashes the listener. Now this should work without any
action from the user.
  • Loading branch information
Dzeri96 committed Mar 14, 2021
1 parent dc9201c commit aac89d9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@

## Installation
1. Make sure `BRIGHTNESS_FILE_PATH` in set_micmute_led.c corresponds to the LED file path on your system.
2. Run `./install.sh`
2. Make sure `mic_name` in micmute_listener_pa.py corresponds to your mic device name. This name can be found within the sources printed out when the client is started. (This will be made more user-friendly with upcoming releases)
3. Run `./install.sh`

## Running
If you have systemd and want to enable the script as soon as you log in, run `systemctl --user enable micmute_listener_pa.service`.

### With systemd
If you want to enable the script as soon as you log in, run `systemctl --user enable micmute_listener_pa.service`.
To start the service immediately, run `systemctl --user start micmute_listener_pa.service`.

### Without systemd
Simply run `~/.local/bin/micmute_listener_pa.py &` after installation. For starting the client at boot, look up your distro's individual way to achieve this.

## Contributions
I'm very intrested in your opinions in terms of the architecture of this service. If you have suggestions on how to avoid SETUID or make the whole thing cleaner or more secure, please start a discussion!
68 changes: 55 additions & 13 deletions micmute_listener_pa.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,72 @@

import pulsectl
import os
pulse = pulsectl.Pulse('my-client-name')
import sys
import signal
pulse = pulsectl.Pulse('micmute-listener')

# TODO: Read this from an external config file
mic_name = 'alsa_input.pci-0000_04_00.6.analog-stereo'

active_index = 1 # This is the index of the source
pulse_event = None

with pulsectl.Pulse('event-printer') as pulse:
def shutdown(signum, frame):
print('Shutting down client...')
pulse.disconnect()
quit(0)

def find_mic_index():
global active_index

for source in pulse.source_list():
if(source.name == mic_name):
active_index = int(source.index)
print('Mic index set: %d' % (active_index))
return

raise RuntimeError('Could not find a device corresponding to %s!' % (mic_name))

def catch_events(ev):
print('Pulse event:', ev)
global pulse_event
pulse_event = ev
### Raise PulseLoopStop for event_listen() to return before timeout (if any)
raise pulsectl.PulseLoopStop

def set_led_value(value):
os.system("/usr/local/bin/set_micmute_led " + str(value))

def init():
pulse.connect(wait= True)

#print('Event types:', pulsectl.PulseEventTypeEnum)
#print('Event facilities:', pulsectl.PulseEventFacilityEnum)
#print('Event masks:', pulsectl.PulseEventMaskEnum)
#print('Source list:', pulse.source_list())

def print_events(ev):
#print('Pulse event:', ev)
global pulse_event
pulse_event = ev
### Raise PulseLoopStop for event_listen() to return before timeout (if any)
raise pulsectl.PulseLoopStop
print('Source list:', pulse.source_list())

find_mic_index()
init_led_value = 0 if pulse.source_info(active_index).mute == 1 else 1
set_led_value(init_led_value)

pulse.event_mask_set('all')
pulse.event_callback_set(print_events)
pulse.event_callback_set(catch_events)


if __name__ == '__main__':
print('Starting the micmute listener...')
signal.signal(signal.SIGINT, shutdown)
init()

while True:
pulse.event_listen()
try:
pulse.event_listen()
except pulsectl.pulsectl.PulseDisconnected:
# TODO: check the docu, maybe this isn't the best way to restart the connection
print('PulseAudio disconnected! Attempting to reconnect...', file=sys.stderr)
init()
continue

if pulse_event.index == active_index:
led_value = 0 if pulse.source_info(active_index).mute == 1 else 1
os.system("/usr/local/bin/set_micmute_led " + str(led_value))
set_led_value(led_value)

0 comments on commit aac89d9

Please sign in to comment.