Connecting media keys globally to foobar2000 on wine
I consider foobar2000 still one of the best audio players, mainly because of it's excellent media library system (for why even DeadBeef did not cut it for me!).
Of course it runs well on linux with wine, however media keys (the extra ones on most keyboards), did not go through when the window was unfocused!
Further investication revealed that even native applications such as VLC did not receive the keypresses when unfocused. (I suppose that's what I get for not running a whole DE, but only Openbox + picom + xfce4-panels.) Soon I knen that MPRIS (Media Player Remote Interfacing Specification) D-Bus interface exists, and an application called playerctl was already created to control all compatible media players with MPRIS.
But being non-native software, foobar2000 does not support MPRIS. One approach I found was to Use the foobar2000 web-interface to expose MPRIS, but unfortunately I could not get it to run in the end. (pip install
and run an application without problems challenge, literally impossible :P)
In the end I decided to create a bash/shell script to call when a media key was pressed, the script then detects if foobar2000 is running and sends the relevant command to the progam via command line. If the foobar2000 is not running, the script just sends the command to playerctl, so that the media keys work globally. (Most of the time when I'd like to use the keys it with foobar2000)
Here is the quick script itself
Note that the arch AUR package I used, foobar2000
includes compability script which allows to call the program like so: foobar2000 -play
etc. Also see how some commands had to be translated and others filtered out.
#!/bin/bash
# default executable
executable="playerctl"
# possible hacky ones
executable_hack_foobar2000="foobar2000"
# default args
arg_prefix=""
arg="$1"
print_help()
{
echo "Usage:"
echo " global_media_keys_handler.sh COMMAND [player_list]"
echo ""
echo " Handles manually defined media players not supporting MPRIS D-Bus Specification"
echo " Prioritizes those players but if none are detected running, passes command to playerctl "
echo ""
echo "Options:"
echo " COMMAND Playback command in a format accepted by playerctl"
echo " player_list Optional comma separated list of players to pass to playerctl"
echo " for manually defining player(s) to control with it (See playerctl -l)"
}
print_error()
{
echo "command $1 is not compatible with $executable"
}
# if no args
if [ $# -eq 0 ]; then
print_help
exit
fi
# check if any hacky program is running, special cases for each
ps cax | grep $executable_hack_foobar2000 > /dev/null
if [ $? -eq 0 ]; then
# set correct executable & argument prefix if necessary
executable="$executable_hack_foobar2000"
arg_prefix="-"
# filter & translate possible arguments
if [ $arg = "play" ] || [ $arg = "pause" ] || [ $arg = "stop" ] || [ $arg = "next" ]; then
arg="$arg"
elif [ $arg = "play-pause" ]; then
arg="playpause"
elif [ $arg = "previous" ]; then
arg="prev"
else
print_error # if this player does not support all arguments
exit
fi
fi
# check if playerctl player list is supplied
if [ -n "$2" ] && [ $executable = "playerctl" ]; then
extra_arg=" -p $2"
else
extra_arg=""
fi
# run command
$executable$extra_arg $arg_prefix$arg