summaryrefslogtreecommitdiff
path: root/ar/.local/bin/statusbar/sb-music
blob: 36f9101f2eb245adbd4c52527f1f3bba5866f1b1 (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
#!/bin/bash

shopt -s extglob

MPD_HOST="${MPD_HOST:-/tmp/mpd_socket}"
export MPD_HOST

truncate_string() {
  local input="$1"
  local max_length="$2"
  if [ "${#input}" -gt "$max_length" ]; then
    local truncated="${input:0:$((max_length - 2))}"
    echo "${truncated%%+( )}.."
  else
    echo "$input"
  fi
}

signal="$(awk -F', *' -v name="${0##*/}" '$2 ~ name {print $3+0}' "${XDG_SOURCES_HOME:-${HOME}/.local/src}/suckless/dwmblocks/config.def.h")"

[ "$signal" -eq 0 ] && {
  pidof -x sb-mpdup >/dev/null 2>&1 || sb-mpdup >/dev/null 2>&1 &
  pidof -x sb-playerctlup >/dev/null 2>&1 || sb-playerctlup >/dev/null 2>&1 &
}

screen_width=$(xrandr | awk '/\*/ {split($1, res, "x"); print res[1]; exit}')
if [ "$screen_width" -le 2048 ]; then
  length="$(grep 'MAX_BLOCK_OUTPUT_LENGTH' ~/.local/src/suckless/dwmblocks/config.def.h | awk '{print $3}')"
  max_length="${length:+$((length / 3))}"
  max_length="${max_length:-15}"
fi

status() {
  if ps -C mpd >/dev/null 2>&1; then
    local artist title prefix indicators current_time total_time
    artist=$(mpc current -f %artist%)
    title=$(mpc current -f %title%)

    if [ "$screen_width" -le 2048 ]; then
      artist=$(truncate_string "$artist" "$max_length")
      title=$(truncate_string "$title" "$max_length")
    fi

    case "$(mpc status %state%)" in
    "playing") prefix="🎵" ;;
    "paused") prefix="⏸" ;;
    *) return ;;
    esac

    indicators=""
    [ "$(mpc status %single%)" = "on" ] && indicators="${indicators}🔂"
    [ "$(mpc status %random%)" = "on" ] && indicators="${indicators}🔀"
    [ "$(mpc status %repeat%)" = "on" ] && indicators="${indicators}🔁"

    case "$signal" in
    0)
      echo "$prefix$artist - $title${indicators:+$indicators}"
      ;;
    [1-9]*)
      current_time=$(mpc status %currenttime%)
      total_time=$(mpc status %totaltime%)
      echo "$prefix$artist - $title ${current_time:+$current_time/}$total_time${indicators:+$indicators}"
      ;;
    *) return ;;
    esac
  fi
}

playerctl_status() {
  command -v playerctl >/dev/null 2>&1 || return

  local output="" player
  while IFS= read -r player; do
    local player_status
    player_status=$(playerctl --player="$player" status 2>/dev/null) || continue

    local play_icon
    case "${player%%.*}" in
    spotify | rhythmbox | audacious | clementine | strawberry) play_icon="🎵" ;;
    vlc | mpv | totem | celluloid) play_icon="🎬" ;;
    firefox | chromium | chrome) play_icon="📺" ;;
    *) play_icon="▶️" ;;
    esac

    local prefix
    case "$player_status" in
    "Playing") prefix="$play_icon" ;;
    "Paused") prefix="⏸" ;;
    *) continue ;;
    esac

    if [[ "$player" == chromium.instance* ]]; then
      local pid proc_name
      pid="${player#chromium.instance}"
      proc_name=$(ps -p "$pid" -o comm= 2>/dev/null)
      [ "$proc_name" = "youtube-music" ] || continue
    else
      continue
    fi

    local artist title
    artist=$(playerctl --player="$player" metadata artist 2>/dev/null)
    title=$(playerctl --player="$player" metadata title 2>/dev/null)

    [ -z "$artist" ] && [ -z "$title" ] && continue

    if [ -n "$max_length" ]; then
      artist=$(truncate_string "$artist" "$max_length")
      title=$(truncate_string "$title" "$max_length")
    fi

    output="${output:+$output | }${prefix}${artist:+$artist - }${title}"
  done < <(playerctl -l 2>/dev/null)

  echo "$output"
}

mpd_output=""
if ps -C mpd >/dev/null 2>&1 && ! mpc status %state% 2>/dev/null | grep -q "stopped"; then
  mpd_output=$(status)
fi

playerctl_output=$(playerctl_status)

if [ -n "$mpd_output" ] && [ -n "$playerctl_output" ]; then
  echo "$mpd_output $playerctl_output"
elif [ -n "$mpd_output" ]; then
  echo "$mpd_output"
elif [ -n "$playerctl_output" ]; then
  echo "$playerctl_output"
fi

case $BLOCK_BUTTON in
1) setsid -f "$TERMINAL" -e ncmpcpp ;; # left click, opens ncmpcpp
2) mpc toggle ;;                       # middle click, pause/unpause
3)                                     # right click
  { [ -n "$(mpc current)" ] && [ -n "$(mpc queued)" ]; } && notify-send "🎵 $(mpc current)" "⏭  $(mpc queued)"
  notify-send "🎵 Music module" "\- Shows mpd song playing and status
- 🎵 if playing
- ⏸ if paused
- 🔂 if single on
- 🔁 if repeat on
- 🔀 if random on
- Left click opens ncmpcpp
- Middle click pauses/unpause
- Scroll changes track"
  ;;
4) mpc prev ;; # scroll up, previous
5) mpc next ;; # scroll down, next
6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac