From 67f5cb9386454d9a3fa2517540de03c2ed6f08f3 Mon Sep 17 00:00:00 2001 From: Yigit Sever Date: Wed, 27 Oct 2021 11:05:01 +0300 Subject: polybar: clean up the scripts --- .config/polybar/scripts/pulseaudio_control | 265 +++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100755 .config/polybar/scripts/pulseaudio_control (limited to '.config/polybar/scripts/pulseaudio_control') diff --git a/.config/polybar/scripts/pulseaudio_control b/.config/polybar/scripts/pulseaudio_control new file mode 100755 index 0000000..7ba2c3f --- /dev/null +++ b/.config/polybar/scripts/pulseaudio_control @@ -0,0 +1,265 @@ +#!/usr/bin/env 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="no" # 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 -- cgit v1.2.3-70-g09d2