Skip to content

Instantly share code, notes, and snippets.

@freb
Created April 28, 2021 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freb/ca0acb767816756d2cd0d8df0586a12e to your computer and use it in GitHub Desktop.
Save freb/ca0acb767816756d2cd0d8df0586a12e to your computer and use it in GitHub Desktop.
#!/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