added volume manager for pipewire and i3blocks
This commit is contained in:
parent
b9b4fd6ddc
commit
c49dd68b2f
|
@ -34,6 +34,11 @@ A collection of standalone python scripts for the slightly more complicated thin
|
||||||
* call `cpu.py 1` to get the avg from last min
|
* call `cpu.py 1` to get the avg from last min
|
||||||
* call `cpu.py 5` to get the avg from last 5 min
|
* call `cpu.py 5` to get the avg from last 5 min
|
||||||
* call `cpu.py 15` to get the avg from last 15 min
|
* call `cpu.py 15` to get the avg from last 15 min
|
||||||
|
* **volume.py**: Now compatible with *pipewire*, parses output of `pactl` to output activ sink and current volume to i3blocks and manages music volume hotkeys.
|
||||||
|
* call `volume.py` without args to output status for i3blocks
|
||||||
|
* call `volume.py vol_up` to increase volume by 5%
|
||||||
|
* call `volume.py vol_down` to decrease volume by 5%
|
||||||
|
* call `volume.py mute` to toggle mute
|
||||||
|
|
||||||
|
|
||||||
## i3block_shell
|
## i3block_shell
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
handler for media keys
|
||||||
|
integrated with pipewire by parsing pactl
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
# signal id to update i3blocks
|
||||||
|
I3BLOCKS_SIGNAL_ID = 10
|
||||||
|
|
||||||
|
|
||||||
|
def get_status():
|
||||||
|
""" returns the activ sink pased in a dict """
|
||||||
|
# get list of sinks
|
||||||
|
state = subprocess.run(["pactl", "list", "sinks"], capture_output=True)
|
||||||
|
state_str = state.stdout.decode()
|
||||||
|
sinks = state_str.split('\n\n')
|
||||||
|
# loop through sinks
|
||||||
|
sinks_dict_list = []
|
||||||
|
for sink in sinks:
|
||||||
|
sink_lines = sink.split('\n')
|
||||||
|
# build sink dict
|
||||||
|
sink_dict = {}
|
||||||
|
for i in sink_lines:
|
||||||
|
if ':' in i:
|
||||||
|
key, value = i.split(':', maxsplit=1)
|
||||||
|
elif '=' in i:
|
||||||
|
key, value = i.split('=')
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
key = key.strip().lower()
|
||||||
|
value = value.strip().strip('"')
|
||||||
|
if value:
|
||||||
|
sink_dict[key] = value
|
||||||
|
# append to list
|
||||||
|
sinks_dict_list.append(sink_dict)
|
||||||
|
# find active
|
||||||
|
if len(sinks_dict_list) == 1:
|
||||||
|
activ_sink = sinks_dict_list[0]
|
||||||
|
else:
|
||||||
|
for sink_dict in sinks_dict_list:
|
||||||
|
sink_name = sink_dict['name']
|
||||||
|
if 'bluez' in sink_name:
|
||||||
|
activ_sink = sink_dict
|
||||||
|
break
|
||||||
|
# return activ
|
||||||
|
return activ_sink
|
||||||
|
|
||||||
|
|
||||||
|
def get_vol(activ_sink):
|
||||||
|
""" get the current volume level of activ sink """
|
||||||
|
vol_string = activ_sink['volume']
|
||||||
|
vol_list = [i for i in vol_string.split(' / ') if '%' in i]
|
||||||
|
vol = int(vol_list[0].strip().strip('%'))
|
||||||
|
return vol
|
||||||
|
|
||||||
|
|
||||||
|
def print_status(activ_sink):
|
||||||
|
""" print status for i3 blocks """
|
||||||
|
mute = activ_sink['mute']
|
||||||
|
# based on sink
|
||||||
|
if 'bluez' in activ_sink['name']:
|
||||||
|
# bluetooth
|
||||||
|
icon = ''
|
||||||
|
elif activ_sink['active port'] == 'analog-output-headphones':
|
||||||
|
# headphones
|
||||||
|
icon = ''
|
||||||
|
elif activ_sink['active port'] == 'analog-output-speaker':
|
||||||
|
# speaker
|
||||||
|
if mute == 'no':
|
||||||
|
icon = ''
|
||||||
|
else:
|
||||||
|
icon = ''
|
||||||
|
# color
|
||||||
|
if mute == 'no':
|
||||||
|
color = "#ffffff"
|
||||||
|
vol = str(get_vol(activ_sink)) + '%'
|
||||||
|
else:
|
||||||
|
color = "#404040"
|
||||||
|
vol = "MUTE"
|
||||||
|
# print three lines
|
||||||
|
print(f'{icon} {vol}')
|
||||||
|
print(f'{icon}')
|
||||||
|
print(color)
|
||||||
|
|
||||||
|
|
||||||
|
def mute(activ_sink):
|
||||||
|
""" toggle mute of activ sink """
|
||||||
|
sink_id = activ_sink['object.id']
|
||||||
|
subprocess.call(['pactl', 'set-sink-mute', sink_id, 'toggle'])
|
||||||
|
|
||||||
|
|
||||||
|
def vol_up(activ_sink):
|
||||||
|
""" increase vol in 5% increments """
|
||||||
|
sink_id = activ_sink['object.id']
|
||||||
|
vol = get_vol(activ_sink)
|
||||||
|
# if uneven vol level
|
||||||
|
if vol % 5 == 0:
|
||||||
|
target_vol = vol + 5
|
||||||
|
else:
|
||||||
|
target_vol = vol + 5 - (vol % 5)
|
||||||
|
# how many times to loop
|
||||||
|
iterations = target_vol - vol
|
||||||
|
for _ in range(iterations):
|
||||||
|
subprocess.call(['pactl', 'set-sink-volume', sink_id, '+1%'])
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def vol_down(activ_sink):
|
||||||
|
""" decrese vol in 5% increments """
|
||||||
|
sink_id = activ_sink['object.id']
|
||||||
|
vol = get_vol(activ_sink)
|
||||||
|
# if uneven vol level
|
||||||
|
if vol % 5 == 0:
|
||||||
|
target_vol = vol - 5
|
||||||
|
else:
|
||||||
|
target_vol = vol - (vol % 5)
|
||||||
|
# how many times to loop
|
||||||
|
iterations = vol - target_vol
|
||||||
|
for _ in range(iterations):
|
||||||
|
subprocess.call(['pactl', 'set-sink-volume', sink_id, '-1%'])
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" main to run """
|
||||||
|
# parse args
|
||||||
|
args = sys.argv
|
||||||
|
activ_sink = get_status()
|
||||||
|
# if args
|
||||||
|
if len(args) > 1:
|
||||||
|
arg = args[1]
|
||||||
|
if arg == 'vol_up':
|
||||||
|
vol_up(activ_sink)
|
||||||
|
elif arg == 'vol_down':
|
||||||
|
vol_down(activ_sink)
|
||||||
|
elif arg == 'mute':
|
||||||
|
mute(activ_sink)
|
||||||
|
activ_sink = get_status()
|
||||||
|
subprocess.call(['pkill', '-RTMIN+' + str(I3BLOCKS_SIGNAL_ID), 'i3blocks'])
|
||||||
|
# status
|
||||||
|
print_status(activ_sink)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue