Krolyxon
Commit af47ed6

Branches

Refs →

aurora.localbinmadd

89 lines · 3.0 KB · Bourne Again Shell (bash)

1#!/bin/sh
2# mpd-add: fuzzy-pick a track from the MPD library and play it right away.
3# Works in a terminal (fzf) or launched from a menu (aurora-run).
4#
5# Usage: mpd-add [-q]
6# -q queue the track right after the current one, but don't jump to it
7
8QUEUE_ONLY=0
9[ "${1:-}" = "-q" ] && QUEUE_ONLY=1
10
11# Notifications replace each other instead of stacking (dunst/mako/swaync).
12notify() { # notify [-u urgency] <title> <body>
13 urgency=normal
14 if [ "$1" = "-u" ]; then urgency=$2; shift 2; fi
15 echo "$1: $2" >&2
16 command -v notify-send >/dev/null 2>&1 || return 0
17 notify-send -a mpd-add -u "$urgency" \
18 -h string:x-canonical-private-synchronous:mpd-add \
19 -h string:x-dunst-stack-tag:mpd-add \
20 "$1" "$2"
21}
22
23if ! mpc status >/dev/null 2>&1; then
24 notify -u critical "MPD unreachable" "Is mpd running?"
25 exit 1
26fi
27
28# One "Artist - Title · Album<TAB>file" line per track (the album makes typing an
29# album name list its songs). Untagged tracks fall back to the file name (minus
30# extension and a leading track number), and the artist is only prefixed when
31# that name doesn't already contain one. Singles (album = title) skip the album.
32library=$(mpc listall -f '%artist%\t%title%\t%album%\t%file%' | awk -F'\t' '{
33 artist = $1; title = $2; album = $3; file = $4
34 if (title == "") {
35 title = file
36 sub(/.*\//, "", title); sub(/\.[^.]*$/, "", title); sub(/^[0-9]+[.)]? *-? */, "", title)
37 if (index(title, " - ")) artist = ""
38 }
39 line = artist != "" ? artist " - " title : title
40 sub(/ - (Single|EP)$/, "", album)
41 if (album != "" && album != title) line = line " · " album
42 print line "\t" file
43}')
44if [ -z "$library" ]; then
45 notify -u critical "MPD library is empty" "Try: mpc update"
46 exit 1
47fi
48
49if [ -t 0 ]; then
50 filename=$(printf '%s\n' "$library" | fzf -d '\t' --with-nth 1 | cut -f2)
51else
52 # aurora-run can't hide a column: show the names, map the index back to the file.
53 n=$(printf '%s\n' "$library" | cut -f1 | aurora-run -d -l 30 -p 'play: ' --index) || exit 0
54 [ "$n" -ge 0 ] 2>/dev/null || exit 0
55 filename=$(printf '%s\n' "$library" | sed -n "$((n + 1))p" | cut -f2)
56fi
57
58# Cancelled (Esc): nothing to do.
59[ -z "$filename" ] && exit 0
60
61# Position of the current song (1-based); empty if nothing is playing/paused.
62cur=$(mpc -f '%position%' current)
63
64if ! mpc insert "$filename" >/dev/null; then
65 notify -u critical "Couldn't add track" "$filename"
66 exit 1
67fi
68
69if [ "$QUEUE_ONLY" -eq 1 ]; then
70 notify "Queued next" "$filename"
71 exit 0
72fi
73
74# Jump straight to the song we just inserted. It lands right after the current
75# song, or at the end of the queue when nothing is playing. Using an explicit
76# position avoids `mpc next`, which misbehaves when stopped or paused.
77if [ -n "$cur" ]; then
78 target=$((cur + 1))
79else
80 target=$(mpc playlist | wc -l)
81fi
82
83if mpc play $target >/dev/null; then
84 now=$(mpc current)
85 notify "Now playing" "${now:-$filename}"
86else
87 notify -u critical "Couldn't start playback" "$filename"
88 exit 1
89fi