Files

78 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""看音频现场: sink 音量 / 声卡各 route 的音量 / 默认设备(排查"响度怪"用).
用法: python3 看音频状态.py
"""
from __future__ import annotations
import json
import subprocess
from typing import Any
def dump() -> list[dict[str, Any]]:
raw = subprocess.run(["pw-dump"], capture_output=True, text=True).stdout
return json.loads(raw)
def vol_of(prm: dict[str, Any]) -> str:
"""把 Volume 参数压成一行."""
cv = prm.get("channelVolumes") or prm.get("volume")
if cv is None:
return "-"
if isinstance(cv, (int, float)):
return f"{cv:.4f}"
vals = [float(v) for v in cv]
if not vals:
return "-"
return "/".join(f"{v:.4f}" for v in vals)
def main() -> None:
d = dump()
print("=== Audio/Sink 节点 ===")
for o in d:
if o.get("type") != "PipeWire:Interface:Node":
continue
p = o.get("info", {}).get("props", {})
if p.get("media.class") not in ("Audio/Sink", "Stream/Output/Audio"):
continue
prms = o.get("info", {}).get("params", {})
vol = "-"
for prm in prms.get("Props", []) or []:
if "volume" in prm or "channelVolumes" in prm:
vol = vol_of(prm)
print(f" id={o['id']:<4} {p.get('media.class'):<20} {p.get('node.name','')}")
print(f" desc={p.get('node.description','')} vol={vol} "
f"state={o.get('info',{}).get('state','')}")
print()
print("=== 声卡(Device) 及其 route 音量 ===")
for o in d:
if o.get("type") != "PipeWire:Interface:Device":
continue
p = o.get("info", {}).get("props", {})
name = p.get("device.name") or p.get("api.alsa.card.name") or ""
if "usb" not in name.lower() and "edifier" not in name.lower():
continue
print(f" id={o['id']} {p.get('node.name','')} ({p.get('device.description','')})")
prms = o.get("info", {}).get("params", {})
print(f" 参数键: {sorted(prms.keys())}")
for prm in prms.get("Profile", []) or []:
print(f" 当前 profile: {prm.get('name','')} ({prm.get('description','')})")
for prm in prms.get("Route", []) or []:
rp = prm.get("props", {})
print(f" route={rp.get('route.name',''):<28} "
f"desc={rp.get('route.description',''):<20} "
f"prio={rp.get('priority','')} vol={vol_of(prm)} "
f"avail={prm.get('available','')}")
for prm in prms.get("EnumRoute", []) or []:
rp = prm.get("props", {})
print(f" [enum] {rp.get('route.name',''):<28} "
f"desc={rp.get('route.description','')} avail={prm.get('available','')}")
if __name__ == "__main__":
main()