-
-
Save freb/ca0acb767816756d2cd0d8df0586a12e to your computer and use it in GitHub Desktop.
This file contains 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
#!/bin/env python3 | |
import os | |
import time | |
import subprocess | |
import argparse | |
# Maps a string contained in name, description, or product_name to our custom name | |
custom_names = { | |
"Plantronics_Blackwire_5220": "PLT 5220", | |
"Plantronics_Blackwire_3220": "PLT 3220", | |
} | |
class Sink: | |
id = None | |
name = "" # primary reference | |
description = "" | |
product_name = "" | |
def __init__(self, id): | |
self.id = id | |
def __repr__(self): | |
# if self.custom_name: | |
# return self.custom_name | |
if self.description: | |
return self.description | |
return self.name | |
@property | |
def custom_name(self): | |
for match, display in custom_names.items(): | |
if self.filter(match): | |
return display | |
return "" | |
def _run_command(self, cmd): | |
# print("RUNNING:", cmd) | |
# .run checks response code and raises Exception if != 0 | |
result = subprocess.run(cmd.split(), check=True, capture_output=True) | |
return result.stdout | |
def volume_add(self, percent): | |
cmd = 'pactl set-sink-volume {} {:+d}%'.format(self.name, percent) | |
self._run_command(cmd) | |
def volume_set(self, percent): | |
cmd = 'pactl set-sink-volume {} {}%'.format(self.name, percent) | |
self._run_command(cmd) | |
def volume_mute_toggle(self): | |
cmd = 'pactl set-sink-mute {} toggle'.format(self.name) | |
self._run_command(cmd) | |
def filter(self, name): | |
for field in [self.name.lower(), self.description.lower(), self.product_name.lower()]: | |
if name.lower() in field: | |
return True | |
return False | |
def parse_sinks(): | |
stream = os.popen('pactl list sinks') | |
sinks = [] | |
for line in stream: | |
if line.startswith("Sink #"): | |
sink = Sink(int(line[6:].strip())) | |
sinks.append(sink) | |
continue | |
if line.startswith("\tName:"): | |
sink.name = line[6:].strip() | |
if line.startswith("\tDescription:"): | |
sink.description = line[14:].strip() | |
continue | |
if line.startswith("\t\tdevice.product.name = "): | |
sink.product_name = line[24:].strip().strip('\"') | |
return sinks | |
# -sink "substr", omitting does on all | |
def main(): | |
parser = argparse.ArgumentParser(description='pactl wrapper') | |
parser.add_argument('--list-sinks', action='store_true') | |
parser.add_argument('--sinks', nargs='*', help='filter for sinks') | |
parser.add_argument('-a', type=int, help='adjust volume percent, e.g. "-2", or 1') | |
parser.add_argument('-s', type=int, help='set volume percent, e.g. "-2", or 1') | |
parser.add_argument('-m', action='store_true', help='toggle mute') | |
args = parser.parse_args() | |
sinks = parse_sinks() | |
if args.list_sinks: | |
for s in sinks: | |
print(s.name) | |
print("\t{}".format(s.product_name)) | |
return | |
if args.sinks: | |
s = [] | |
for fltr in args.sinks: | |
for sink in sinks: | |
if sink.filter(fltr): | |
s.append(sink) | |
sinks = s | |
print(sinks) | |
if args.a: | |
for sink in sinks: | |
print('adjusting volume for:', sink.custom_name) | |
sink.volume_add(args.a) | |
return | |
if args.s: | |
for sink in sinks: | |
print('setting volume for:', sink.custom_name) | |
sink.volume_set(args.s) | |
return | |
if args.m: | |
for sink in sinks: | |
print('setting mute for:', sink.custom_name) | |
sink.volume_mute_toggle() | |
return | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment