├── features.md ├── main.sh ├── modules ├── barcolr ├── icon ├── mpdctrl ├── mpdinfo ├── mpdstate ├── progressbar └── volbar ├── readme.md └── todo.md /features.md: -------------------------------------------------------------------------------- 1 | # List of Existing Features 2 | 3 | ## Clickable areas 4 | 5 | -------------------------------------------------------------------------------- /main.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Include the other scripts/modules/functions in this directory 4 | _include() 5 | { 6 | DIR="$(dirname $0)" 7 | FILE="$DIR/$1" 8 | 9 | if [ -f "$FILE" ]; then 10 | . "$FILE" 11 | else 12 | printf "\033[33m%s\033[0m: Not Found\n" "$FILE" && exit 1 13 | fi 14 | } 15 | 16 | test ! "$(pgrep mpd)" && { 17 | printf '\033[33m%s:\033[0m process not found\n' 'mpd' && exit 1 18 | } 19 | 20 | # Fetches color via xrdb 21 | _include "modules/barcolr" 22 | # MPD info fetcher 23 | _include "modules/mpdinfo" 24 | # Prints the respective icons that are present in the siji font 25 | _include "modules/icon" 26 | # Clickable Media Keys for playback controls with icons 27 | _include "modules/mpdctrl" 28 | # Draw a Progress bar for total played time using mkb 29 | _include "modules/progressbar" 30 | # Draw a Progress bar for the current volume level using mkb 31 | _include "modules/volbar" 32 | # Determine mpd's state and set the music icon's color and pause message 33 | _include "modules/mpdstate" 34 | 35 | # Update interval, see sleep(1) for more details 36 | T=0.2 37 | 38 | PROGNAME="$(basename $0)" 39 | 40 | # Font for the iconic glyphs: https://github.com/stark/siji/ 41 | siji="-wuncon-siji-medium-r-normal--10-100-75-75-c-80-iso10646-1" 42 | # Text font 43 | neepmod='-jmk-neepmod-medium-r-normal--11-100-75-75-c-60-iso8859-1' 44 | 45 | FONTS="-f $neepmod -f $siji" 46 | # Background Color 47 | BG="$(barcolr bg)" 48 | # Foreground Color 49 | FG="$(barcolr 7)" 50 | 51 | OFFX=0 52 | OFFY=0 53 | HEIGHT=20 54 | WIDTH=$(xrandr | grep '*' | cut -d 'x' -f1) 55 | 56 | # lemonbar geomtery 57 | GEOMETRY=${WIDTH}x${HEIGHT}+${OFFX}+${OFFY} 58 | 59 | # mkb char 60 | BCHAR= 61 | 62 | _bar() 63 | { 64 | OPTS="-d -p -B $BG -F $FG $FONTS -u 2 -g $GEOMETRY -a 15" 65 | 66 | lemonbar $OPTS 67 | } 68 | 69 | _fgcolr() 70 | { 71 | local COLOR=$1 72 | local TEXT="$2" 73 | 74 | echo "%{F$(barcolr $COLOR)}$TEXT%{F-}" 75 | } 76 | 77 | _print() 78 | { 79 | # Icon color when paused/playing 80 | STATE_ICON="$(_music_state icon)" 81 | # Pause Message 82 | STATE_MSG="$(_music_state msg)" 83 | # Now Playing 84 | NP="$(_fgcolr 15 "`_music_info title`") $(_fgcolr 8 by) $(_fgcolr 14 "`_music_info artist`")" 85 | # Playback Control Keys 86 | MKEYS="$(_music_ctrl prev) $(_music_ctrl rwd) $(_music_ctrl toggle) $(_music_ctrl fwd) $(_music_ctrl next)" 87 | # Progress bar 88 | PBAR="$(_music_info played) $(progressbar) $(_music_info total)" 89 | # Volume up 90 | V_UP="$(_fgcolr 2 "`_music_ctrl vup`")" 91 | # Volume down 92 | V_DOWN="$(_fgcolr 3 "`_music_ctrl vdn`")" 93 | # Volume bar 94 | VBAR="$V_DOWN $(volbar) $V_UP" 95 | 96 | # Left Side 97 | L="%{l}$STATE_ICON $NP $STATE_MSG" 98 | # Center 99 | C="%{c}$MKEYS $PBAR" 100 | # Right Side 101 | R="%{r}$(icon vol) $(_fgcolr 14 `_music_info vol`) $VBAR %{A3:killall -g -15 $PROGNAME:}$(icon opt)%{A} " 102 | 103 | echo "${L} ${C} ${R}" 104 | } 105 | 106 | # The spell that binds everything together 107 | while [ $? -eq 0 ]; do 108 | _print && sleep $T 109 | done | _bar | sh > /dev/null 110 | 111 | exit 0 112 | -------------------------------------------------------------------------------- /modules/barcolr: -------------------------------------------------------------------------------- 1 | barcolr() 2 | { 3 | case $1 in 4 | bg) # Background 5 | xrdb -query | awk '/background/ {print $2}' 6 | ;; 7 | fg) # Foreground 8 | xrdb -query | awk '/foreground/ {print $2}' 9 | ;; 10 | 0) # Black 11 | xrdb -query | awk '/^\*color0:/ {print $2}' 12 | ;; 13 | 1) # Red 14 | xrdb -query | awk '/^\*color1:/ {print $2}' 15 | ;; 16 | 2) # Green 17 | xrdb -query | awk '/^\*color2:/ {print $2}' 18 | ;; 19 | 3) # Yellow 20 | xrdb -query | awk '/^\*color3:/ {print $2}' 21 | ;; 22 | 4) # Blue 23 | xrdb -query | awk '/^\*color4:/ {print $2}' 24 | ;; 25 | 5) # Magenta 26 | xrdb -query | awk '/^\*color5:/ {print $2}' 27 | ;; 28 | 6) # Cyan 29 | xrdb -query | awk '/^\*color6:/ {print $2}' 30 | ;; 31 | 7) # White 32 | xrdb -query | awk '/^\*color7:/ {print $2}' 33 | ;; 34 | 8) # Bold Black 35 | xrdb -query | awk '/^\*color8:/ {print $2}' 36 | ;; 37 | 9) # Bold Red 38 | xrdb -query | awk '/^\*color9:/ {print $2}' 39 | ;; 40 | 10) # Bold Green 41 | xrdb -query | awk '/^\*color10:/ {print $2}' 42 | ;; 43 | 11) # Bold Yellow 44 | xrdb -query | awk '/^\*color11:/ {print $2}' 45 | ;; 46 | 12) # Bold Blue 47 | xrdb -query | awk '/^\*color12:/ {print $2}' 48 | ;; 49 | 13) # Bold Magenta 50 | xrdb -query | awk '/^\*color13:/ {print $2}' 51 | ;; 52 | 14) # Bold Cyan 53 | xrdb -query | awk '/^\*color14:/ {print $2}' 54 | ;; 55 | 15) # Bold White 56 | xrdb -query | awk '/^\*color15:/ {print $2}' 57 | ;; 58 | *) 59 | printf '\033[31m%s error\[0m: Unknown color\n' 'barcolr' 60 | exit 1 61 | ;; 62 | esac 63 | 64 | return 0 65 | } 66 | 67 | # vim: set ft=sh noet: 68 | -------------------------------------------------------------------------------- /modules/icon: -------------------------------------------------------------------------------- 1 | # Function for fetching icons 2 | icon() 3 | { 4 | case $1 in 5 | toggle|tog) 6 | echo "" 7 | ;; 8 | previous|prv) 9 | echo "" 10 | ;; 11 | next) 12 | echo "" 13 | ;; 14 | forward|fwd) 15 | echo "" 16 | ;; 17 | rewind|rwd) 18 | echo "" 19 | ;; 20 | vol) 21 | echo "" 22 | ;; 23 | vol_up|vup) 24 | echo "+" 25 | ;; 26 | vol_down|vdn) 27 | echo "-" 28 | ;; 29 | vol_mute|mute) 30 | echo "$(_fgcolor 3 '\ue052')" 31 | ;; 32 | opt) 33 | echo "" 34 | ;; 35 | music) 36 | echo "" 37 | ;; 38 | *) 39 | printf '\033[31micon error\033[0m:%s' 'Unknown Option' 40 | exit 1 41 | esac 42 | 43 | return 0 44 | } 45 | # vim: set ft=sh noet: 46 | -------------------------------------------------------------------------------- /modules/mpdctrl: -------------------------------------------------------------------------------- 1 | 2 | 3 | # TODO: Make this function work 4 | _vol_toggle() 5 | { 6 | VOL=$(_music_info vol) 7 | [ $VOL -ne 0 ] && CUR_VOL=$VOL || VOLSTATE='mute' 8 | 9 | case $VOL in 10 | *) 11 | mpc volume 0 12 | export VOL_ICON="$(icon mute)" 13 | ;; 14 | 0) 15 | mpc volume $CUR_VOL 16 | export VOL_ICON="$(icon vol)" 17 | ;; 18 | esac 19 | } 20 | 21 | _music_ctrl() 22 | { 23 | case $1 in 24 | vol) 25 | echo "%{A:_vol_toggle}$VOL_ICON%{A}" 26 | ;; 27 | play) 28 | echo "%{A:mpc play:}$(icon toggle)%{A}" 29 | ;; 30 | pause) 31 | echo "%{A:mpc pause:}$(icon toggle)%{A}" 32 | ;; 33 | stop) 34 | echo "%{A:mpc stop:}$(icon toggle)%{A}" 35 | ;; 36 | prev) 37 | echo "%{A:mpc prev:}$(icon prv)%{A}" 38 | ;; 39 | next) 40 | echo "%{A:mpc next:}$(icon next)%{A}" 41 | ;; 42 | rewind|rwd) 43 | echo "%{A:mpc seek -1:}%{A3:mpc seek -5:}$(icon rwd)%{A}%{A}" 44 | ;; 45 | forward|fwd) 46 | echo "%{A:mpc seek +1:}%{A3:mpc seek +5:}$(icon fwd)%{A}%{A}" 47 | ;; 48 | vol_up|vup) 49 | echo "%{A:mpc vol +1:}%{A3:mpc vol +5:}$(icon vol_up)%{A}%{A}" 50 | ;; 51 | vol_up|vdn) 52 | echo "%{A:mpc vol -1:}%{A3:mpc vol -5:}$(icon vol_down)%{A}%{A}" 53 | ;; 54 | toggle) 55 | echo "%{A:mpc toggle:}%{A3:mpc stop:}$(icon toggle)%{A}%{A}" 56 | ;; 57 | *) 58 | printf '\033[33mmpdctrl\033[0m error: %s\n' 'Unknown Option' 59 | exit 1 60 | ;; 61 | esac 62 | return 0 63 | } 64 | 65 | # vim: set ft=sh noet: 66 | -------------------------------------------------------------------------------- /modules/mpdinfo: -------------------------------------------------------------------------------- 1 | 2 | _music_info() 3 | { 4 | case $1 in 5 | state) 6 | mpc status | awk 'NR==2 {print $1}' | tr -d '[]' 7 | ;; 8 | now_playing|current|np) 9 | mpc current 10 | ;; 11 | artist) 12 | mpc -f "[%artist%]" | head -n 1 13 | ;; 14 | album) 15 | mpc -f "[%album%]" | head -n 1 16 | ;; 17 | title) 18 | mpc -f "[%title%]|[%file%]" | head -n 1 19 | ;; 20 | total) 21 | mpc -f "%time%" | head -n 1 22 | ;; 23 | played) 24 | mpc status | awk 'NR==2 {print $3}' | cut -d '/' -f 1 25 | ;; 26 | track) 27 | mpc | awk 'NR==2 {print $2}' | cut -d '#' -f2 28 | ;; 29 | vol) 30 | mpc volume | tr -cd '0-9' 31 | ;; 32 | played_perc) 33 | mpc status | awk 'NR==2 { print $4 }' | tr -d '()' 34 | ;; 35 | *) 36 | printf "$0: %s\n" "Unknown Option" 37 | exit 1 38 | ;; 39 | esac 40 | 41 | return 0 42 | } 43 | # vim: set ft=sh noet: 44 | -------------------------------------------------------------------------------- /modules/mpdstate: -------------------------------------------------------------------------------- 1 | # Function for various mpd error checking 2 | _music_state() 3 | { 4 | local STATE="$(_music_info state)" 5 | 6 | if [ "$STATE" = 'paused' ]; then 7 | # Pause Message 8 | local MSG="%{F$(barcolr 8)}Paused at%{F-} %{+u}%{U$(barcolr 3)} $(_music_info played_perc) %{U-}%{-u}" 9 | # Icon Color when paused 10 | local ICON="%{F$(barcolr 3)}%{R} $(icon music) %{R}%{F-}" 11 | elif [ "$STATE" = 'playing' ]; then 12 | # Icon Color when playing 13 | local ICON="%{F$(barcolr 4)}%{R} $(icon music) %{R}%{F-}" 14 | fi 15 | 16 | case $1 in 17 | msg) 18 | echo "$MSG" 19 | ;; 20 | icon) 21 | echo "$ICON" 22 | ;; 23 | *) 24 | printf "\033[33m%s\033[0m: Unknown Option\n" "$0" 25 | ;; 26 | esac 27 | } 28 | # vim: set ft=sh noet: 29 | -------------------------------------------------------------------------------- /modules/progressbar: -------------------------------------------------------------------------------- 1 | # Function for displaying played perc via mkb 2 | progressbar() 3 | { 4 | BAR_SIZE=30 5 | C1="%{F$(barcolr 4)}$BCHAR%{F-}" 6 | C2="%{F$(barcolr 5)}$BCHAR%{F-}" 7 | 8 | _music_info played_perc | SIZE=$BAR_SIZE CHAR1="$C1" CHAR2="$C2" SEP='' START='' END='' mkb 9 | } 10 | 11 | # vim: set ft=sh noet: 12 | -------------------------------------------------------------------------------- /modules/volbar: -------------------------------------------------------------------------------- 1 | # Function for displaying played perc via mkb 2 | volbar() 3 | { 4 | BAR_SIZE=10 5 | C1="%{F$(barcolr 4)}$BCHAR%{F-}" 6 | C2="%{F$(barcolr 5)}$BCHAR%{F-}" 7 | 8 | _music_info vol | SIZE=$BAR_SIZE CHAR1="$C1" CHAR2="$C2" SEP='' START='' END='' mkb 9 | } 10 | 11 | # vim: set ft=sh noet: 12 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # About Music Bar 2 | 3 | Just a simple wrapper around lemonbar/mpd/mpc to display info and control the playback. 4 | 5 | Support for cmus may be added later, but that's not decided yet. 6 | 7 | 8 | ## Dependencies 9 | 10 | - [Lemonbar](https://github.com/lemonboy/bar) for the bar duh ... 11 | - [Siji font](https://github.com/stark/siji/) for the iconic glyphs 12 | - [Mkb](http://git.z3bra.org/mkb/log.html) for drawing the progress bar 13 | 14 | ## Todo 15 | 16 | See the **[todo.md](https://github.com/stark/musicbar/blob/master/todo.md)** file for more details. 17 | 18 | ## Contributions 19 | 20 | The code still needs **alot** of work 21 | 22 | So Pull Requests are more than welcome :) 23 | 24 | Read the **[todo.md](https://github.com/stark/musicbar/blob/master/todo.md)** for more details. 25 | 26 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # Desired Features 2 | 3 | - [ ] Visual feedback by reversing the attribute (Not limited to underline/overline) of an icon on click. 4 | - [ ] Different color of feedback based on the mouse button. 5 | - [ ] Add support for cmus by writing modules. 6 | 7 | # Code refactoring 8 | 9 | - [ ] Massive clean up needed ! 10 | - [ ] The code needs to be more modular so that it's easiy to add/remove modules, adding support for other players such as cmus shouldn't breaking anything. 11 | - [ ] A separate config file with a set of standard environment variables (lemonbar example: FONT, GEOM, color names, etc). 12 | - [ ] Improve readability (add more comments, sensible variable and function names). 13 | - [ ] Code optimization (Use of less pipes through better regex). 14 | 15 | # Documentation 16 | 17 | - [ ] Document each of the modules. 18 | - [ ] Explain the necessary functions and variables which makes all this work. 19 | 20 | --------------------------------------------------------------------------------