Last active
September 3, 2025 19:50
-
-
Save erincerys/681bf686b5013a1aa2fb10477a0eabef to your computer and use it in GitHub Desktop.
Audio play/pause keybind for i3wm and pipewire, tested with Spotify, Strawberry, and Firefox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# usage: place in ~/.i3/config | |
bindsym XF86AudioPrev exec playerctl previous | |
bindsym XF86AudioNext exec playerctl next | |
bindsym XF86AudioPlay exec playerctl -p "$(~/.local/bin/get-player-name)" play-pause | |
bindsym XF86AudioStop exec playerctl -p "$(~/.local/bin/get-player-name)" pause | |
bindsym Mod4+F5 exec playerctl previous | |
bindsym Mod4+F6 exec playerctl next | |
bindsym Mod4+F7 exec playerctl -p "$(~/.local/bin/get-player-name)" play-pause | |
bindsym Mod4+F8 exec playerctl -p "$(~/.local/bin/get-player-name)" stop | |
bindsym Mod4+Home exec playerctl previous | |
bindsym Mod4+End exec playerctl next | |
bindsym Mod4+Next exec playerctl -p "$(~/.local/bin/get-player-name)" play-pause |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# purpose: query pipewire for application name that is actively playing audio | |
# usage: symlink file to ~/.local/share/bin/get-active-player | |
pw-dump | jq -r ' | |
.[] | | |
select((.type//"") | test("Node")) | | |
( .info?.props // .props // {} ) as $p | | |
($p["media.class"] // "") as $mc | | |
select($mc | test("Stream/Output/Audio|Audio/Stream/Output|Output/Audio|Audio/Output")) | | |
.id | |
' | while read -r id; do | |
out=$(pw-cli info "$id" 2>/dev/null) || continue | |
state=$(printf '%s\n' "$out" | sed -n 's/.*state: *"\([^"]*\)".*/\1/p') | |
[ "$state" != "running" ] && continue | |
app=$(printf '%s\n' "$out" \ | |
| sed -n -e 's/.*application.name = *"\([^"]*\)".*/\1/p' \ | |
-e 's/.*application.process.binary = *"\([^"]*\)".*/\1/p' \ | |
-e 's/.*media.name = *"\([^"]*\)".*/\1/p' \ | |
| head -n1 \ | |
) | |
printf '%s\n' "${app:-unknown}" | |
done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -a | |
# logic flow: | |
# 1. call other script | |
# 2. return active player name and cache it in a state file, if successful response | |
# 3. otherwise, return player name from cache/state file, if set | |
# 4. otherwise, return 'unknown' | |
# usage: | |
# - symlink file to ~/.local/share/bin/get-player | |
# - create ~/.local/state directory if needed | |
_STATE="$HOME/.local/state/player" | |
test -f "$_STATE" && read _CACHE < "$_STATE" | |
read -a _PLAYERS < <( | |
"$HOME/.local/bin/get-active-player-name" | | |
tr '[:upper:]' '[:lower:]' | |
) | |
_PLAYER="${_PLAYERS[0]}" | |
if [ -n "$_PLAYER" ]; then | |
if [[ "$_PLAYER" = 'unknown' && -z "$_CACHE" ]]; then | |
echo -n "$_PLAYER" >&2 | |
elif [[ "$_PLAYER" != 'unknown' || -z "$_CACHE" ]]; then | |
[ "$_PLAYER" = 'firefox' ] && | |
_PLAYER="$(playerctl -l | grep $_PLAYER)" | |
echo -n "$_PLAYER" | tee "$_STATE" | |
fi | |
elif [[ -z "$_PLAYER" || -n "$_CACHE" ]]; then | |
cat "$_STATE" | |
else | |
printf 'unknown' >&2 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment