123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #!/usr/bin/env python
- ## Written by demure (demuredemeanor)
- ## This program depends on pactl to work
- ## This tool makes per application muting a simple and fast process.
- from __future__ import print_function ## Needed for python2/3 print
- import sys ## Needed for argv
- import subprocess ## Need for running `pactl`
- import re ## Needed for regex
- ## Get overall sink state
- def get_state():
- state = {}
- ## Get current sink states, decode needed for python3 strong types
- stream = subprocess.check_output(["pactl", "list", "sink-inputs"]).decode('utf-8')
- ## Take "Sink Input" and application.process.binary and assign to dict.
- ## Assign mute state for each sink
- for nums,bins,mutes in zip(re.findall("Sink Input #(\d+)", stream),\
- re.findall("application.process.binary\s=\s\"(\S+)\"", stream),\
- re.findall("Mute:\s(\w+)", stream)):
- state.update({nums:[bins, mutes]})
- return state
- ## Print Sink Numbers, binary name, and mute state -- if present
- def print_state():
- state = get_state()
- if bool(state):
- for sink in state:
- print("Sink Number:", sink, "\tMuted:", state[sink][1], "\tbin:", state[sink][0])
- else:
- print("No applications are reported to be outputting souund.")
- return
- ## Checks if sink exists, then toggles if present
- def mute_toggle(sink):
- state = get_state()
- if sink in state:
- subprocess.check_output(["pactl", "set-sink-input-mute", sink, "toggle"])
- else:
- print("Sink number [" + sink + "] not found!")
- return
- ## Checks state for string, if single result will pass to mute_toggle
- def string_to_sink(string):
- state = get_state()
- matches=[]
- for nums in state:
- if state[nums][0] == string:
- matches.append(nums)
- if len(matches) > 1:
- print("Too many matches!")
- elif len(matches) == 0:
- print("No matches.")
- else:
- mute_toggle(matches[0])
- return
- ## Parse the command line arguments
- def parse_argv(argv):
- arg1=argv[1]
- ## Single augment
- if len(argv) == 2:
- ## Option list
- if arg1 == "-l" or arg1 == "--list" or arg1 == "list":
- print_state()
- return
- ## Option mute fail
- if arg1 == "-m" or arg1 == "--mute" or arg1 == "mute":
- print("Missing SINK number!")
- msg_help()
- return
- ## Option string fail
- if arg1 == "-s" or arg1 == "--string" or arg1 == "string":
- print("Missing string NAME!")
- return
- ## Option help
- if arg1 == "-h" or arg1 == "--help" or arg1 == "help":
- msg_help()
- return
- ## Option version
- if arg1 == "-V" or arg1 == "--version" or arg1 == "version":
- msg_version()
- return
- ## Run -m if only sink number passed
- if re.match("^(\d+)$", arg1):
- mute_toggle(arg1)
- return
- ## If they get here, the didn't match; print help.
- print("["+arg1+"] is not a valid option!")
- msg_help()
- return
- ## Two Augments
- elif len(argv) == 3:
- arg2=argv[2]
- ## Option mute
- if arg1 == "-m" or arg1 == "--mute" or arg1 == "mute":
- if re.match("^(\d+)$", arg2):
- mute_toggle(arg2)
- else:
- print("["+arg2+"] is not a valid sink input!")
- msg_help()
- return
- ## Option string
- if arg1 == "-s" or arg1 == "--string" or arg1 == "string":
- string_to_sink(arg2)
- else:
- print("["+arg1+"] is not a valid option!")
- msg_help()
- return
- ## Too many Augments
- else:
- print("Too many augments!")
- msg_help()
- return
- ## Print help message
- def msg_help():
- help_msg=\
- """
- Usage: premute [OPTION...]
- When run without OPTION, will output sink list
- When run with SINK as option, will mute SINK number
- -l, --list List Sink Inputs
- -m, --mute SINK Mute Sink number
- -s, --string NAME Attempt bin name mute
- -V, --version Display version information
- -h, --help Display this help message
- """
- print(help_msg)
- return
- ## Print version number message
- def msg_version():
- version_msg="permute version: 0.2.0"
- print(version_msg)
- return
- ## Main
- def main(argv):
- if len(argv) > 1:
- parse_argv(argv)
- else:
- print_state()
- if __name__ == '__main__':
- main(sys.argv)
|