pulseaudio: allow to configure the sink

When we have multiple sinks, this change allows to have all/some of them
available in i3pystatus and to identify which one is currently the
default. Also it allows to configure if we want that the hook
change_sink move all inputs to the new sink or not.
This commit is contained in:
Mehdi Abaakouk 2016-10-05 23:29:42 +02:00
parent 962f376f43
commit d1e8f6f1b7

View File

@ -21,14 +21,18 @@ class PulseAudio(Module, ColorRangeModule):
(the literal value for -infinity is `-`)
* `{muted}` the value of one of the `muted` or `unmuted` settings
* `{volume_bar}` unicode bar showing volume
* `{selected}` show the format_selected string if selected sink is the configured one
"""
settings = (
"format",
("format_muted", "optional format string to use when muted"),
("format_selected", "string used to mark this sink if selected"),
"muted", "unmuted",
"color_muted", "color_unmuted",
("step", "percentage to increment volume on scroll"),
("sink", "sink name to use, None means pulseaudio default"),
("move_sink_inputs", "Move all sink inputs when we change the default sink"),
("bar_type", "type of volume bar. Allowed values are 'vertical' or 'horizontal'"),
("multi_colors", "whether or not to change the color from "
"'color_muted' to 'color_unmuted' based on volume percentage"),
@ -39,11 +43,15 @@ class PulseAudio(Module, ColorRangeModule):
unmuted = ""
format = "♪: {volume}"
format_muted = None
format_selected = " 🗸"
currently_muted = False
has_amixer = False
color_muted = "#FF0000"
color_unmuted = "#FFFFFF"
sink = None
move_sink_inputs = True
step = 5
multi_colors = False
bar_type = 'vertical'
@ -83,13 +91,16 @@ class PulseAudio(Module, ColorRangeModule):
def request_update(self, context):
"""Requests a sink info update (sink_info_cb is called)"""
pa_operation_unref(pa_context_get_sink_info_by_name(
context, self.sink.encode(), self._sink_info_cb, None))
context, self.current_sink.encode(), self._sink_info_cb, None))
def success_cb(self, context, success, userdata):
pass
@property
def sink(self):
def current_sink(self):
if self.sink is not None:
return self.sink
self.sinks = subprocess.check_output(['pactl', 'list', 'short', 'sinks'],
universal_newlines=True).splitlines()
bestsink = None
@ -167,34 +178,47 @@ class PulseAudio(Module, ColorRangeModule):
else:
raise Exception("bar_type must be 'vertical' or 'horizontal'")
selected = ""
dump = subprocess.check_output("pacmd dump".split(), universal_newlines=True)
for line in dump.split("\n"):
if line.startswith("set-default-sink"):
default_sink = line.split()[1]
if default_sink == self.current_sink:
selected = self.format_selected
self.output = {
"color": color,
"full_text": output_format.format(
muted=muted,
volume=volume_percent,
db=volume_db,
volume_bar=volume_bar),
volume_bar=volume_bar,
selected=selected),
}
self.send_output()
def change_sink(self):
curr_sink = self.sink
sinks = list(s.split()[1] for s in self.sinks)
next_sink = (sinks.index(curr_sink) + 1) % len(sinks)
if self.sink is None:
next_sink = sinks[(sinks.index(self.current_sink) + 1) %
len(sinks)]
else:
next_sink = self.current_sink
sink_inputs = subprocess.check_output("pacmd list-sink-inputs".split(),
universal_newlines=True)
for input_index in re.findall('index:\s+(\d+)', sink_inputs):
command = "pacmd move-sink-input {} {}".format(input_index, sinks[next_sink])
subprocess.call(command.split())
subprocess.call("pacmd set-default-sink {}".format(sinks[next_sink]).split())
if self.move_sink_inputs:
sink_inputs = subprocess.check_output("pacmd list-sink-inputs".split(),
universal_newlines=True)
for input_index in re.findall('index:\s+(\d+)', sink_inputs):
command = "pacmd move-sink-input {} {}".format(input_index, next_sink)
subprocess.call(command.split())
subprocess.call("pacmd set-default-sink {}".format(next_sink).split())
def switch_mute(self):
subprocess.call(['pactl', '--', 'set-sink-mute', self.sink, "toggle"])
subprocess.call(['pactl', '--', 'set-sink-mute', self.current_sink, "toggle"])
def increase_volume(self):
subprocess.call(['pactl', '--', 'set-sink-volume', self.sink, "+%s%%" % self.step])
subprocess.call(['pactl', '--', 'set-sink-volume', self.current_sink, "+%s%%" % self.step])
def decrease_volume(self):
subprocess.call(['pactl', '--', 'set-sink-volume', self.sink, "-%s%%" % self.step])
subprocess.call(['pactl', '--', 'set-sink-volume', self.current_sink, "-%s%%" % self.step])