aboutsummaryrefslogtreecommitdiff
path: root/bin/player
blob: 9baa2d0d26367fb9328a34a08b6e9d2e7fb95551 (plain) (blame)
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
#!/bin/sh
set -eu

usage() {
	cat <<-'EOF'
		Usage:
		  player ACTION
		  player -h
	EOF
}

help() {
	cat <<-'EOF'


		Options:
		  -h, --help    show this message

		  ACTION        one of:
		                - backward:       go back 5 seconds
		                - forward:        go forward 5 seconds
		                - previous:       go to the previous track
		                - next:           go to the next track
		                - play-pause:     play/pause
		                - rotate:         rotate across available MPRIS players
		                - synopsis:       show the current MPRIS player and title
		                - synopsis-f:     show the current MPRIS player and title


		Manipulate the MPRIS audio player.


		Examples:

		  Change the current MPRIS player:

		    $ player synopsis


		  Play/pause:

		    $ player play-pause
	EOF
}


for flag in "$@"; do
	case "$flag" in
		(--)
			break
			;;
		(--help)
			usage
			help
			exit
			;;
		(*)
			;;
	esac
done

while getopts 'P:h' flag; do
	case "$flag" in
		(h)
			usage
			help
			exit
			;;
		(*)
			usage >&2
			exit 2
			;;
	esac
done
shift $((OPTIND - 1))
ACTION="${1:-}"

eval "$(assert-arg -- "$ACTION" 'ACTION')"



CURRENT_PLAYER_PATH="$XDG_CACHE_HOME"/euandreh-mpris-player.txt
CURRENT_PLAYER="$(cat "$CURRENT_PLAYER_PATH" 2>/dev/null ||:)"
AVAILABLE_PLAYERS="$(playerctl --list-all | LANG=POSIX.UTF-8 sort)"

pick_first() {
	printf '%s\n' "$AVAILABLE_PLAYERS" | head -n1
}

next_player() {
	if [ -z "$CURRENT_PLAYER" ]; then
		pick_first
	elif ! printf '%s\n' "$AVAILABLE_PLAYERS" | grep -q "$CURRENT_PLAYER"; then
		# Unknown $CURRENT_PLAYER, pick anyone
		pick_first
	else
		INDEX="$(printf '%s\n' "$AVAILABLE_PLAYERS" | grep -n "$CURRENT_PLAYER" | cut -d: -f1)"
		LENGTH="$(printf '%s\n' "$AVAILABLE_PLAYERS" | wc -l)"
		if [ "$INDEX" = "$LENGTH" ]; then
			# Reached the end of the $AVAILABLE_PLAYERS list, wrapping
			pick_first
		else
			# Get the next player instead
			printf '%s\n' "$AVAILABLE_PLAYERS" | awk -v idx="$INDEX" 'NR == idx+1 {print}'
		fi
	fi
}

format_player_name() {
	sed 's|^firefox\.instance.*$|firefox|'
}

formatted_player_title() {
	TITLE="$(
		playerctl --player="$CURRENT_PLAYER" metadata xesam:title \
			2>/dev/null ||:
		)"
	if [ -z "$TITLE" ]; then
		TITLE="$(
			playerctl --player="$CURRENT_PLAYER" metadata xesam:url |
				uri -d |
				sed 's|^.*/home/andreh/Downloads/||'
		)"
	fi
	if [ ${#TITLE} -gt 62 ]; then
		printf '%s...\n' "$(printf '%s' "$TITLE" | head -c 60)"
	else
		printf '%s\n' "$TITLE"
	fi
}

case "$ACTION" in
	backward)
		playerctl --player="$CURRENT_PLAYER" position 5-
		;;
	forward)
		playerctl --player="$CURRENT_PLAYER" position 5+
		;;
	previous)
		playerctl --player="$CURRENT_PLAYER" previous
		;;
	next)
		playerctl --player="$CURRENT_PLAYER" next
		;;
	play-pause)
		playerctl --player="$CURRENT_PLAYER" play-pause
		;;
	rotate)
		PLAYER="$(next_player)"
		printf '%s\n' "$PLAYER" > "$CURRENT_PLAYER_PATH"
		notify-send -t 1000 -- \
			"$(printf '%s' "$PLAYER" | format_player_name)" \
			'current MPRIS target'
		;;
	synopsis)
		printf '%s: %s\n' \
			"$(printf '%s\n' "$CURRENT_PLAYER" | format_player_name)" \
			"$(formatted_player_title)"
		;;
	synopsis-f)
		tail -f "$CURRENT_PLAYER_PATH" 2>/dev/null | format_player_name
		;;
	*)
		printf 'Bad ACTION: "%s".\n\n' "$ACTION" >&2
		usage >&2
		exit 2
		;;
esac