#!/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
exit
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