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