91 lines
2.5 KiB
Python
91 lines
2.5 KiB
Python
import asyncio
|
|
import json
|
|
|
|
from greendeck.config import PulseAudioActionConfig
|
|
|
|
|
|
async def get_sink_info(
|
|
action_config: PulseAudioActionConfig,
|
|
) -> tuple[int | None, int | None]:
|
|
proc = await asyncio.create_subprocess_exec(
|
|
"pactl",
|
|
*["--format=json", "list", "sink-inputs"],
|
|
stdin=asyncio.subprocess.DEVNULL,
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.STDOUT,
|
|
)
|
|
stdout, stderr = await proc.communicate()
|
|
if proc.returncode != 0:
|
|
print(f"error {proc.returncode}")
|
|
print(stderr)
|
|
return None, None
|
|
|
|
data = json.loads(stdout)
|
|
index = None
|
|
for entry in data:
|
|
if entry["properties"]["application.name"] == action_config.application_name:
|
|
index = entry["index"]
|
|
volume = int(
|
|
round(
|
|
sum([v["value"] for v in entry["volume"].values()])
|
|
/ len(entry["volume"]),
|
|
0,
|
|
)
|
|
)
|
|
print(index, volume, entry["volume"])
|
|
return index, volume
|
|
|
|
print(f"unable to locate sink {action_config.application_name}")
|
|
return None, None
|
|
|
|
|
|
volume_step = int(round(0x10000 * 0.05, 0))
|
|
|
|
|
|
async def handle_pulseaudio_action(
|
|
action_config: PulseAudioActionConfig,
|
|
) -> None:
|
|
|
|
index, volume = await get_sink_info(action_config)
|
|
if index is None:
|
|
return
|
|
|
|
match action_config.action:
|
|
case "volume-up":
|
|
new_volume = min(volume + volume_step, 0x10000)
|
|
command = [
|
|
"set-sink-input-volume",
|
|
f"{index}",
|
|
f"{new_volume}",
|
|
]
|
|
|
|
case "volume-down":
|
|
new_volume = max(volume - volume_step, 0x00000)
|
|
command = [
|
|
"set-sink-input-volume",
|
|
f"{index}",
|
|
f"{new_volume}",
|
|
]
|
|
|
|
case "toggle-mute":
|
|
command = ["set-sink-input-mute", f"{index}", "toggle"]
|
|
|
|
case _:
|
|
print(f"unknown action {action_config.action}")
|
|
return
|
|
|
|
proc = await asyncio.create_subprocess_exec(
|
|
"pactl",
|
|
*command,
|
|
stdin=asyncio.subprocess.DEVNULL,
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.PIPE,
|
|
)
|
|
stdout, stderr = await proc.communicate()
|
|
if proc.returncode != 0:
|
|
print(f"retcode: {proc.returncode}")
|
|
print(stdout)
|
|
print(stderr)
|
|
|
|
index, volume = await get_sink_info(action_config)
|