Created
March 12, 2025 18:51
-
-
Save jpsutton/d5e742756c4b3077bce59d5b3ec7dd34 to your computer and use it in GitHub Desktop.
Toggle all microphones mute status with on-screen indicator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import pulsectl | |
import dbus | |
def show_notification(title, message, icon_name): | |
""" | |
Show a desktop notification using D-Bus directly. | |
Args: | |
title: The notification title | |
message: The notification message body | |
icon_name: Name of the icon to display | |
""" | |
import dbus | |
try: | |
# Connect to the D-Bus session bus | |
bus = dbus.SessionBus() | |
# Get the notifications service | |
notify_service = bus.get_object( | |
'org.freedesktop.Notifications', | |
'/org/freedesktop/Notifications' | |
) | |
# Get the notifications interface | |
notify_interface = dbus.Interface( | |
notify_service, | |
'org.freedesktop.Notifications' | |
) | |
# Send the notification | |
notify_interface.Notify( | |
"Mic Toggle", # App name | |
0, # Replace id (0 = new notification) | |
icon_name, # Icon name | |
title, # Title | |
message, # Body | |
[], # Actions | |
{}, # Hints | |
2000 # Timeout in ms (2 seconds) | |
) | |
except Exception as e: | |
# Fall back to print if D-Bus fails | |
print(f"Notification failed: {e}") | |
print(f"{title}: {message}") | |
def toggle_all_mics(): | |
""" | |
Toggle mute status of all input devices (microphones) in the PulseAudio system. | |
Shows an on-screen notification of the action. | |
Returns True if mics are now muted, False if unmuted. | |
""" | |
with pulsectl.Pulse('mic-toggle') as pulse: | |
# Get all source (input) devices that are actually microphones | |
all_sources = pulse.source_list() | |
# Filter for actual microphone devices - exclude monitors and non-mic devices | |
microphones = list(filter(lambda x: "input" in x.name.split(".")[0].lower(), all_sources)) | |
# If no microphones found, show notification and exit early | |
if not microphones: | |
show_notification( | |
"Mic Toggle", | |
"No microphones found in the system", | |
"microphone-sensitivity-muted" | |
) | |
return False | |
# Check if any mics are already unmuted to determine current state | |
any_unmuted = any(mic.mute == 0 for mic in microphones) | |
# If any mic is unmuted, we'll mute all | |
# If all mics are muted, we'll unmute all | |
new_mute = 1 if any_unmuted else 0 | |
# Apply mute/unmute only to microphone sources | |
for mic in microphones: | |
pulse.source_mute(mic.index, new_mute) | |
# Show notification based on action | |
icon = 'microphone-sensitivity-muted' if new_mute else 'microphone-sensitivity-high' | |
message = 'All microphones muted' if new_mute else 'All microphones unmuted' | |
show_notification("Mic Toggle", message, icon) | |
return new_mute == 1 # Return True if we muted, False if we unmuted | |
if __name__ == "__main__": | |
status = toggle_all_mics() | |
print(f"Microphones {'muted' if status else 'unmuted'}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment