Skip to content

Instantly share code, notes, and snippets.

@crpb
Created August 26, 2025 03:10
Show Gist options
  • Select an option

  • Save crpb/ec62dc2880897a6f6e1a2e9b772a1067 to your computer and use it in GitHub Desktop.

Select an option

Save crpb/ec62dc2880897a6f6e1a2e9b772a1067 to your computer and use it in GitHub Desktop.
modified it a bit ... much /(°o°)\
#!/usr/bin/env bash
# ok so how this shit works:
# it launches playerctl command that watches for changes
# every time there's a change it sends fzf an event
# fzf then executes omega cursed preview command
# aint going to explain how it works but yeah
#
# <cb> /me did some changes here and there /(°o°)\
# <cb> btw, chafa should detect -f by it's own.
#
# depends on curl, fzf, playerctl, chafa, bash (duh)
touch /tmp/player-control-fzf-port ; chmod 0600 $_
touch /tmp/player-control-artwork ; chmod 0600 $_
cleanup() {
rm -f /tmp/player-control-fzf-port
rm -f /tmp/player-control-artwork
kill "$fzf_pid" 2>/dev/null
kill "$read_pid" 2>/dev/null
kill $(jobs -l | awk '{print $2}') 2>/dev/null
}
trap cleanup INT HUP TERM ERR EXIT
export FZF_API_KEY="$(head -c 32 /dev/urandom 2>&1 | base64)"
export FZF_DEFAULT_COMMAND='true' # noop
preview_cmd=$(
cat<<'EOF'
[ -z {} ] && exit;
md=$(playerctl -p {} metadata);
art="$(awk '$2 == "mpris:artUrl" {print $3}' <<< "$md")";
if [ -n "$art" ]; then
if [[ "$art" =~ ^(https|http|ftp)://* ]]; then
tmpart=/tmp/player-control-artwork;
if curl -L -s -o "$tmpart" "$art"; then
art="$tmpart";
fi;
fi;
if echo "$art" | grep -q 'base64'; then
echo "$art" | cut -d ',' -f 2- | base64 -d | chafa -s "${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES / 2))" --align hcenter --dither none;
else
art="${art#file://}";
: "${art//+/ }"; printf -v art_dec '%b' "${_//%/\\x}";
chafa -s "${FZF_PREVIEW_COLUMNS}x$((FZF_PREVIEW_LINES / 2))" --align hcenter --dither none "$art_dec";
fi;
fi;
printf "$(playerctl -p {} metadata --format '\nArtist\t{{artist}}\nAlbum\t{{album}}\nDisc\t{{xesam:discNumber}}\nYear\t{{xesam:contentCreated}}\nTrack\t{{xesam:trackNumber}}\nTitle\t{{title}}\nTime\t{{duration(position)}} / {{duration(mpris:length)}}\n')" |awk '$2!="" || $1==""';
printf 'Player Volume: %.2f\n' "$(playerctl -p {} volume)";
printf 'Global %s\n ' "$(wpctl get-volume @DEFAULT_SINK@)"
printf "\nAdditional Data:";
echo "$md" | awk '$2!~/xesam:(title|artist|album|contentCreated|url|trackNumber|discNumber)/ && $3 != "" && $2!~/mpris:(artUrl|length)/ { sub(/^.+?:/, "", $2); printf $2"\t"; for ( i=3;i<=NF;i++ ) { printf $i""FS }; printf "\n" }';
EOF
)
fzf \
--sync \
--listen 127.0.0.1:0 \
--bind 'start:execute-silent:echo $FZF_PORT >/tmp/player-control-fzf-port' \
--disabled \
--with-shell 'bash -c' \
--bind "result:change-preview($preview_cmd)" \
--preview-window 'right,65%,cycle' \
--tabstop 8 \
--preview-label 'SPACE to play/pause, < and > to prev/next' \
--preview-label-pos bottom \
--bind 'space:execute-silent(playerctl -p {} play-pause)' \
--bind '>:execute-silent:playerctl -p {} next' \
--bind '<:execute-silent:playerctl -p {} previous' \
--bind 'left:execute-silent:playerctl -p {} position 3-' \
--bind 'right:execute-silent:playerctl -p {} position 3+' \
--bind 'alt-right:execute-silent:playerctl -p {} volume 0.03+' \
--bind 'alt-left:execute-silent:playerctl -p {} volume 0.03-' \
--bind 'alt-up:execute-silent:wpctl set-volume @DEFAULT_SINK@ 0.03+' \
--bind 'alt-down:execute-silent:wpctl set-volume @DEFAULT_SINK@ 0.03-' \
&
fzf_pid="$!"
while [ -z "$FZF_PORT" ]; do
sleep 0.1
FZF_PORT="$(cat /tmp/player-control-fzf-port)"
done
# follow position as this will (hopefilly) send continous changes which trigger
# refresh-preview / reload-*sync* was also necessary to get immediate updates.
playerctl -Faf '{{duration(position)}}' metadata | while read -r dummy; do
curl -X POST \
-H "x-api-key: ${FZF_API_KEY}" \
-d 'reload-sync:playerctl -al' \
127.0.0.1:"${FZF_PORT}"
done &
#while read -r dummy; do
#curl -X POST \
# -H "x-api-key: ${FZF_API_KEY}" \
# -d 'reload(playerctl -al)+refresh-preview' \
# 127.0.0.1:"${FZF_PORT}"
#done < <(playerctl -Faf '{{duration(position)}}' metadata)
read_pid="$!"
wait -n "$fzf_pid" "$read_pid"
#wait -n "$fzf_pid"
cleanup
@crpb
Copy link
Author

crpb commented Aug 26, 2025

@heather7283 as this is originally yours... here are my modifications.
not pretty but it works. and i guess instead of creating this cat << 'EOF' one could just create a tmpfile with the scriptcontent and run that instead to haven an easier time ... ¯_(ツ)_/¯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment