-
-
Notifications
You must be signed in to change notification settings - Fork 899
Player
Print the music player name that is currently active
| Module type | player |
| Default order | 47 (only used by --gen-config) |
| Module source | src/modules/player/player.c |
| Detection source |
src/detection/media/ (shared with Media) |
An alias of the Media module that prints only the player instead of the song. It
reads the same shared FFMediaResult and prints a single line:
Media Player: Youtube (Google Chrome)
The value is a "pretty" name built from two fields: when the media has a URL, the site's name is
derived from it and the player is appended in parentheses. Without a URL the line is just the player
name, e.g. Spotify.
Identical to Media: player has no detection source of its own and calls
ffDetectMedia().
| Platform | Implementation | Notes |
|---|---|---|
| Linux | media_linux.c |
MPRIS over the session DBus |
| FreeBSD / OpenBSD / NetBSD / GNU/Hurd | media_linux.c |
Same code; needs DBus |
| Windows | media_windows.cpp |
WinRT GlobalSystemMediaTransportControlsSessionManager
|
| macOS | media_apple.m |
MediaRemote, or a Perl helper process on macOS 15.4+ |
| Android | none | No detection source is referenced |
| Solaris / illumos | none | No detection source is referenced |
| Haiku | none | No detection source is referenced |
On a platform without a backend the module reports the backend's error (for example
winrt: GetCurrentSession() failed on Windows with no media app open), not a "not supported" message.
| Key | Type | Default | Description |
|---|---|---|---|
key |
string | Media Player |
Module key. A single space hides the key and the separator |
keyColor |
color | – | Overrides display.color.keys
|
keyIcon |
string | built-in glyph | Printed when display.key.type includes the icon bit. Any glyph works; "" prints none. |
keyWidth |
integer | – | Overrides display.key.width
|
outputColor |
color | – | Overrides display.color.output
|
format |
string | – | Custom output format (see below) |
condition |
object | – | Show the module only if the conditions match |
There is no module-specific option — not even percent, which media has. Every key other than
the generic ones produces Unknown JSON key ….
The player that is reported is not chosen here either: general.playerName (the --player-name flag)
selects it, and the same setting drives media. It cannot be set from the module's own object.
Run fastfetch -h player-format for the authoritative list.
| Variable | Description |
|---|---|
{player} |
Pretty player name — the value the default line prints |
{name} |
Player name, exactly as the backend reported it |
{id} |
Player identifier: the MPRIS bus name on Linux, the bundle id on macOS, the AppUserModelId on Windows |
{url} |
Media URL, when the backend provides one |
None of the four is marked * in the help output, so none is available in the key format.
The difference between {player} and {name} is only the website prefix: {name} is the raw backend
string (Google Chrome) while {player} is the composed one (Youtube (Google Chrome)). When there
is no URL — or the URL does not start with http:// / https:// — the two are identical.
This is the only output the module ever produces in JSON, whether or not a player is detected:
ffGeneratePlayerJsonResult() writes that error and returns false without calling the detection
layer at all. There is no result object, and --show-errors changes nothing because the error is
not routed through ffPrintError().
To get the player in machine-readable form, read the player object of the Media
module instead — player.name, player.id and player.url correspond to {name}, {id} and
{url}.
// The raw player name instead of the pretty one
{ "type": "player", "format": "{name}" }// Site and identifier
{ "type": "player", "format": "{player} ({id})" }// Follow one player (top-level setting, not a module option)
{ "general": { "playerName": "spotify" }, "modules": [ { "type": "player" } ] }// Rename the line, since the default key is two words
{ "type": "player", "key": "Now playing in" }-
The JSON output is always an error.
{"type": "player"}in a--format jsonrun yieldsPlayer module is an alias of Media moduleand nothing else. Usemediaif the value is needed by a script. -
The default key is
Media Player, notPlayer. The module's type name (player) and its display name differ, sokeyWidthanddisplay.key.widthalign on the two-word name, and a config that filters on the key text has to matchMedia Player. -
The website prefix is skipped only for
spotifyandvlc, and the test is on the id, not the name.ffStrbufIgnCaseEqualS(&media->playerId, "spotify")compares the player identifier, which is the bare MPRIS bus name on Linux but a fullAppUserModelIdon Windows and a bundle id on macOS. The exemption therefore only really applies on Linux: a Windows Spotify reports an id likeSpotifyAB.SpotifyMusic_…!Spotify, which is not equal tospotify. -
The site name is derived by crude string surgery. Everything up to and including
https://,http://,https://www.orhttp://www.is dropped, then the rest is cut at the first/and at the last.. Sohttps://music.youtube.com/watch?…becomesmusic.youtube— the subdomain is kept, and the first letter is only capitalised when no.remains at all. Other schemes (file://,spotify:track:…) leave{player}equal to{name}. -
A player that reports no name is an error, not an empty line. The module distinguishes two
failures: the backend's own error (
No media found,winrt: GetCurrentSession() failed, …) is printed first, and a successful detection whoseplayerstring is empty yieldsNo media player detected. -
Errors are invisible by default. Both messages go through
ffPrintError(), which obeysdisplay.showErrors; with its defaultfalsethe module simply prints nothing. -
{url}is Linux-only. It comes from the MPRISxesam:urlkey, so on Windows and macOS it is always empty — and therefore{player}and{name}are always the same there.
ffPrintPlayer() calls ffDetectMedia(false) — the same cached result the media module uses, so
the two never probe the system twice in one run, and saveCover = false means no artwork is written.
The pretty name is built in the module, not in the detection layer:
- If
urlis non-empty and the player id is neitherspotifynorvlc(case-insensitively), the scheme and an optional leadingwww.are skipped by adding a fixed offset into the string (12, 11, 8 or 7 characters). - The remainder is cut before the first
/(dropping the path) and before the last.(dropping the TLD). - If something is left over and it contains no
., the first byte is upper-cased withtoupper. - The player name is appended, wrapped in
( … )when step 2 left a site name.
Step 2 can empty the string — that happens when the host has nothing before its last dot, as in
https://./ — and then the module falls back to the bare player name. A dotless host such as
https://localhost/ survives both cuts and is simply capitalised to Localhost.
[ { "type": "Player", "error": "Player module is an alias of Media module" } ]