blob: a080d657fe4f96717398202ddbafb2cfa8e80b21 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
#!/bin/bash
##################################################################
# Polybar Pulseaudio Control #
# https://github.com/marioortizmanero/polybar-pulseaudio-control #
##################################################################
# Script configuration (more info in the README)
OSD="no" # On Screen Display message for KDE if enabled
INC=2 # Increment when lowering/rising the volume
MAX_VOL=100 # Maximum volume
AUTOSYNC="no" # All programs have the same volume if enabled
VOLUME_ICONS=( " " " " " " ) # Volume icons array, from lower volume to higher
MUTED_ICON=" " # Muted volume icon
MUTED_COLOR="%{F#A9AA83}" # Color when the audio is muted
DEFAULT_SINK_ICON="" # The default sink icon if a custom one isn't found
CUSTOM_SINK_ICONS=("" "" "") # Custom sink icons in index of sink order
NOTIFICATIONS="yes" # Notifications when switching sinks if enabled
SINK_BLACKLIST=( ) # Index blacklist for sinks when switching between them
# Environment constants
LANGUAGE=en_US # Functions of this scripts depends on English outputs of pactl
# Global script variables
isMuted="no"
activeSink=""
endColor="%{F-}"
function getCurVol {
curVol=$(pacmd list-sinks | grep -A 15 'index: '"$activeSink"'' | grep 'volume:' | grep -E -v 'base volume:' | awk -F : '{print $3}' | grep -o -P '.{0,3}%'| sed s/.$// | tr -d ' ')
}
function getCurSink {
activeSink=$(pacmd list-sinks | awk '/* index:/{print $3}')
}
function volMuteStatus {
isMuted=$(pacmd list-sinks | grep -A 15 "index: $activeSink" | awk '/muted/{ print $2}')
}
function getSinkInputs {
inputArray=$(pacmd list-sink-inputs | grep -B 4 "sink: $1 " | awk '/index:/{print $2}')
}
function volUp {
getCurVol
maxLimit=$((MAX_VOL - INC))
if [ "$curVol" -le "$MAX_VOL" ] && [ "$curVol" -ge "$maxLimit" ]; then
pactl set-sink-volume "$activeSink" "$MAX_VOL%"
elif [ "$curVol" -lt "$maxLimit" ]; then
pactl set-sink-volume "$activeSink" "+$INC%"
fi
getCurVol
if [ ${OSD} = "yes" ]; then
qdbus org.kde.kded /modules/kosd showVolume "$curVol" 0
fi
if [ ${AUTOSYNC} = "yes" ]; then
volSync
fi
}
function volDown {
pactl set-sink-volume "$activeSink" "-$INC%"
getCurVol
if [ ${OSD} = "yes" ]; then
qdbus org.kde.kded /modules/kosd showVolume "$curVol" 0
fi
if [ ${AUTOSYNC} = "yes" ]; then
volSync
fi
}
function volSync {
getSinkInputs "$activeSink"
getCurVol
for each in $inputArray; do
pactl set-sink-input-volume "$each" "$curVol%"
done
}
function volMute {
case "$1" in
mute)
pactl set-sink-mute "$activeSink" 1
curVol=0
status=1
;;
unmute)
pactl set-sink-mute "$activeSink" 0
getCurVol
status=0
;;
esac
if [ ${OSD} = "yes" ]; then
qdbus org.kde.kded /modules/kosd showVolume ${curVol} ${status}
fi
}
function changeDevice {
# Treat pulseaudio sink list to avoid calling pacmd list-sinks twice
o_pulseaudio=$(pacmd list-sinks| grep -e 'index' -e 'device.description')
# Get all sink indices in a list
sinks=($(echo "$o_pulseaudio" | grep index | awk -F': ' '{print $2}'))
# Get present default sink index
activeSink=$(echo "$o_pulseaudio" | grep "\* index" | awk -F': ' '{print $2}')
# Set new sink index, checks that it's not in the blacklist
newSink=$activeSink
# Remove blacklist devices from the sink list
sinks=($(comm -23 <(echo "${sinks[@]}" | tr ' ' '\n' | sort) <(echo "${SINK_BLACKLIST[@]}" | tr ' ' '\n' | sort) | tr '\n' ' '))
# If the resulting list is empty, do nothing
if [ -z "${sinks}" ]; then exit; fi
# If the current sink is greater or equal than last one, pick the first
# sink in the list. Otherwise just pick the next sink avaliable.
if [ "${activeSink}" -ge "${sinks[-1]}" ]; then
newSink=${sinks[0]}
else
for sink in "${sinks[@]}"; do
if [ "${activeSink}" -lt "${sink}" ]; then
newSink=$sink
break
fi
done
fi
# The new sink is set
pacmd set-default-sink "${newSink}"
# Move all audio threads to new sink
inputs=$(pactl list sink-inputs short | cut -f 1)
for i in $inputs; do
pacmd move-sink-input "$i" "$newSink"
done
if [ $NOTIFICATIONS = "yes" ]; then
sendNotification
fi
}
function sendNotification {
o_pulseaudio=$(pacmd list-sinks| grep -e 'index' -e 'device.description')
deviceName=$(echo "$o_pulseaudio" | sed -n '/* index/{n;p;}' | grep -o '".*"' | sed 's/"//g')
notify-send "Output cycle" "Changed output to ${deviceName}" --icon=audio-headphones-symbolic
}
function listen {
firstrun=0
pactl subscribe 2>/dev/null | {
while true; do
{
# If this is the first time just continue
# and print the current state
# Otherwise wait for events
# This is to prevent the module being empty until
# an event occurs
if [ $firstrun -eq 0 ]
then
firstrun=1
else
read -r event || break
if ! echo "$event" | grep -e "on card" -e "on sink" -e "on server"
then
# Avoid double events
continue
fi
fi
} &>/dev/null
output
done
}
}
function output() {
if [ -z "$(pgrep pulseaudio)" ]; then echo "Pulseaudio not running"; return 1; fi
getCurSink
getCurVol
volMuteStatus
# Fixed volume icons over max volume
iconsLen="${#VOLUME_ICONS[@]}"
if [ "$iconsLen" -ne 0 ]; then
volSplit=$(( MAX_VOL / iconsLen ))
for (( i=1; i<=iconsLen; i++ )); do
if (( i*volSplit >= curVol )); then
volIcon="${VOLUME_ICONS[$((i-1))]}"
break
fi
done
else
volIcon=""
fi
# Uses custom sink icon if the array contains one
sinksLen=${#CUSTOM_SINK_ICONS[@]}
if [ "$activeSink" -le "$((sinksLen - 1))" ]; then
sinkIcon=${CUSTOM_SINK_ICONS[$activeSink]}
else
sinkIcon=$DEFAULT_SINK_ICON
fi
# Showing the formatted message
if [ "${isMuted}" = "yes" ]; then
echo "${MUTED_COLOR}${MUTED_ICON}${curVol}% ${sinkIcon} ${activeSink}${endColor}"
else
echo "${volIcon}${curVol}% ${sinkIcon} ${activeSink}"
fi
}
getCurSink
case "$1" in
--up)
volUp
;;
--down)
volDown
;;
--togmute)
volMuteStatus
if [ "$isMuted" = "yes" ]
then
volMute unmute
else
volMute mute
fi
;;
--mute)
volMute mute
;;
--unmute)
volMute unmute
;;
--sync)
volSync
;;
--listen)
# Listen for changes and immediately create new output for the bar
# This is faster than having the script on an interval
listen
;;
--change)
# Changes the audio device
changeDevice
;;
*)
# By default print output for bar
output
;;
esac
|