Media player control
(This is part of a larger series on finding your footing on Arch Linux.)
Goal: Trigger common media player actions (e.g. play, pause, skip forward, etc.) using convenient keyboard shortcuts. Best served with this series’s volume control guide.
References:
What’s involved
There are three main players in the game here:
-
The media player remote interfacing specification (MPRIS), a system-wide API for controlling media players managed by the freedesktop.org.
playerctl
, a utility for sending commands to any program implementing the MPRIS specification. Supported MPRIS client programs include:- The Firefox and Chromium web browsers
- VLC
- mpv (via the
mpv-mpris
plugin)
See ArchWiki: MPRIS/Supported clients for a longer list of media players that support MPRIS.
xbindkeys
, a utility for defining key bindings in X.
Procedure
There are two independent tasks in this article: (1) learning the commands to control playerctl
and (2) binding these commands to keyboard keys using xbindkeys
.
Using playerctl
Hello world
First install the playerctl
package:
sudo pacman -S playerctl
The playerctl
utility offers intuitively-named commands; we’ll use two:
playerctl play-pause
(toggle play/pause for the current media player)playerctl next|previous
(skip to the next or previous track)
See man playerctl
for a clearly-described list of other commands.
Manual usage of playerctl
is straightforward.
For example:
- First play some audio or video in an MPRIS client (e.g. play a YouTube video in Firefox, an MP3 file with VLC, etc.).
- With the media playing, run e.g.
playerctl play-pause
from a command line. The media player should pause. - Run
playerctl play-pause
again. The media player should being playing again.
Running other playerctl
commands is analogous, e.g. playerctl next
, playerctl status
, etc.
Multiple media players
By default playerctl
sends commands to the first-available media player.
If you have multiple media players open at once, you can distinguish between them with the --player
option, e.g.
# Pause media in VLC
playerctl --player=vlc pause
# Play media in Firefox
playerctl --player=firefox play
Useful: playerctl --list-all
lists all active media players that can be controlled with playerctl
.
Seriously, take 10 minutes and read man playerctl
—you’ll find more cool stuff, e.g. you can use the playerctld
daemon to make playerctl
send commands to the last-active player instead of the first-available player.
Using playerctl
with mpv
The excellent mpv
media player requires the mpv-mpris
plugin to work with the MPRIS interface and playerctl
.
Install the mpv-mpris
package (sudo pacman -S mpv-mpris
) and you should be able to control mpv
like any other MPRIS-compatible media player e.g.
playerctl --player=mpv play-pause
Key bindings for media controls
We’ll do this using xbindkeys
.
You need two pieces of information to define a key binding:
-
The X11 key symbol (keysym) of the key you want to bind. (
xbindkeys
identifies keyboard keys by their X11 keysym, which is, loosely, just a short code name for the key.) -
The program you want to run when the key is pressed (e.g.
playerctl play-pause
for media control). You can then usexbindkeys
to bind the keysym to the program.
Detect key symbols
You can identify X11 keysyms with the xev
(X events) utility:
open a shell and run xev
, type the key you wish to bind, and record the keysym.
Here is an example xev
output for the A
and F10
keys on my ThinkPad T460 (I’ve highlighted the keysyms):
# The keysym for the "A" key is "a"
KeyPress event, serial 34, synthetic NO, window 0x2800001,
root 0x7ad, subw 0x0, time 682173681, (-383,347), root:(909,369),
state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
XLookupString gives 1 bytes: (61) "a"
XmbLookupString gives 1 bytes: (61) "a"
XFilterEvent returns: False
# The keysym for the "F10/Search" key is "XF86Search"
KeyPress event, serial 35, synthetic NO, window 0x2200001,
root 0x79b, subw 0x0, time 152154488, (-581,393), root:(103,415),
state 0x0, keycode 225 (keysym 0x1008ff1b, XF86Search), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
The keysyms are a
and XF86Search
.
You have to do a bit of digging through xev
’s verbose output here; alternatively you could run xev | grep keysym
to only print the keysym line.
Define key bindings in .xbindkeysrc
It’s easy: first create the ~/.xbindkeysrc
configuration file; you can do this manually or run:
# Generate a default xbindkeys config file with commented-out examples
xbindkeys --defaults > ~/.xbindkeysrc
Then define key bindings in xbindkeysrc
file with the general syntax:
# Place shell command in quotes and keysym on a new line
"SHELL-COMMAND"
KEYSYM
Here is example:
# Use XF86Search for play/pause
"playerctl play-pause"
XF86Search
This key binding will run the command playerctl play-pause
whenever the key with keysym XF86Search
(which happens to be F10
on a ThinkPad T460; see xev
output above) is pressed.
You can probably take if from here and define key bindings for any playerctl
commands that strike your fancy; consult man playerctl
to see all available commands.
For more information and examples using xbindkeys
see ArchWiki: Xbindkeys.
Activate key bindings
-
Run
xbindkeys
in a shell to activate the just-defined key bindings. -
Make changes permanent: place the line
xbindkeys
above the line that starts your window manager or DE in your~/.xinitrc
file, which will load key bindings each time you start X. Here is an example:# Activate X key bindings xbindkeys # Start the i3 window manager (or whatever WM or DE you use) exec i3
See ArchWiki: Xbindkeys/Making changes permanent for more information.