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-mprisplugin)
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-pausefrom a command line. The media player should pause. - Run
playerctl play-pauseagain. 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. (
xbindkeysidentifies 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-pausefor media control). You can then usexbindkeysto 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
xbindkeysin a shell to activate the just-defined key bindings. -
Make changes permanent: place the line
xbindkeysabove the line that starts your window manager or DE in your~/.xinitrcfile, 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 i3See ArchWiki: Xbindkeys/Making changes permanent for more information.