Now Playing

Play, pause and skip Spotify, Music, a browser or any MPRIS player

palupdated 2026-10-27MediaComes with pal󱔓Menu bar: Now Playing, Playing

Open in pal

Comes with pal, so a new install already has it; the button finds it in pal again if you removed it. This page can't see what your pal has installed.

Now Playing: One row per player: a show on the living-room TV from its own extension first, Spotify playing with the position, Music paused, a browser with nothing loaded
One row per player: a show on the living-room TV from its own extension first, Spotify playing with the position, Music paused, a browser with nothing loaded
Now Playing: The actions on a row: open the TV's own remote, pause, next, previous, copy the track
The actions on a row: open the TV's own remote, pause, next, previous, copy the track
Now Playing: The playing track found from the root by its title
The playing track found from the root by its title
1 of 3

What it does

Control what is playing in Spotify, Music, a browser or any other player: play, pause and skip from the panel, with the track on the bar.

  • One row per player with the track, artist, cover and progress
  • Every player the system knows about on macOS (a browser, VLC), and MPRIS players on Linux
  • What your other extensions play comes first: a show on the Apple TV, Spotify on another device, Jellyfin; enter opens that extension's own view
  • The bar item leaves alone a playback another extension's own item already shows, so nothing is on the bar twice
  • enter plays or pauses, cmd+right and cmd+left skip
  • cmd+c copies artist - title, cmd+o opens the track or the app
  • The playing track is found from the root by its title or artist
  • A bar item with the track; its popover shows the cover, progress and controls
  • One Playing card on the glance strip for whatever plays, the newest first, with an "also" line for a second

Palettes 1

  • Now Playingmedialive

    One row per player with the track and its artwork.

    • ↵Play or pause
    • ⌘→Next track
    • ⌘←Previous track
    • ⌘CCopy artist - title
    • ⌘OOpen the track in its player

Actions

  • OpenOn a player another extension publishes: that extension's own view (the Apple TV's remote, Spotify's lyrics).↵
  • Play or pauseToggles; the row's tag follows (cmd+enter on a published player).↵
  • Next track⌘→
  • Previous track⌘←
  • Copy trackartist - title.⌘C
  • Open in Spotify / MusicThe track's url, else the app on macOS.⌘O

Settings

Extension, [extensions.media]

exclude
none list

Players this extension leaves to another (the Spotify extension's own item, say), by app name (Spotify, Music, Google Chrome) or player id (spotify, music, system): the bar item and the root's Now row skip them; the palette still lists them.

Defaults shown. Change them in pal's settings window or in the config file.

The README

Everything Now Playing does, key by key, from the extension's own README.md

Now Playing

One row per running player: the track as the title, artist and album as the subtitle, the cover (the system's Now Playing artwork on macOS, else the player's artwork url, else the app's icon), the position (42:12 / 1:06:03) and a playing / paused / stopped tag, with the player's name next to it. A player with nothing loaded reads "Nothing playing" with the player's name; one that is playing but reports no track (Chrome with a YouTube tab on macOS gives the position and nothing else) is its app's name, with the position as the subtitle. A live palette: read again on every show through the core's media capability, so the track that is on right now is a root result too (type its title or artist at the root), and the position is the core's estimate at that moment. With no player running the one row says so, and on Linux how to see players.

What your other extensions play comes first: the Apple TV, Spotify on any device, a Jellyfin session (the player control, docs/design/controls.md), named by its app and device ("YouTube · Living room"). Enter opens that extension's own view (the Apple TV's remote, Spotify's lyrics); cmd+enter plays or pauses it, cmd+right and cmd+left skip. One that shows the same playback as a system row (Spotify on this Mac) drops that row. The bar item leaves alone a playback whose extension's own item is on the strip, so nothing is on the bar twice and no extension's own item is replaced.

Every control keeps the palette up and lists again, so the tag follows what you did; a player that refuses (Music not running, a player that has no next track) is a toast with its message.

Keyboard

keys action what
enter Play / Pause toggles; the row's tag follows
cmd+right Next track
cmd+left Previous track
cmd+c Copy track copies artist - title
cmd+o Open in Spotify / Music / ... the track's url (Spotify's spotify:track: link), else the app on macOS

A row for a player with nothing loaded has only the three transport actions.

Setup

One setting under [extensions.media], one on the item. Cover on the bar (artwork, off, a now-playing item setting under [bar.items."media/now-playing".settings]): the cover instead of the note on the menu bar strip, only when the cover is square (a 24 pt picture of anything else is a smudge); the popover shows the cover either way. Leave to another extension (exclude, empty): players this extension leaves to another, by app name or player id (Spotify, music): the bar item and the root's Now row skip them (the Spotify extension shows its own); the palette still lists them. When the strip is drawn is the item's paused rule (Settings > Bar): hidden while the player is not playing; turn its Hidden off and a paused track stays, muted. Keeping the glyph with no player at all (muted, its popover saying nothing plays) is the core's show = "always" under [bar.items."media/now-playing"] (docs/config.md). What is listed depends on what the core's media capability can see:

  • macOS: Spotify and Music through AppleScript, only while the app is running (the check is NSRunningApplication, so pal never launches one to ask); Spotify gives the artwork url and the track url. The first AppleScript run asks whether pal may control the app (the Automation permission). The system-wide Now Playing (any other player: a browser, VLC, IINA) is one more row, from the MediaRemote adapter pal bundles (mediaremote-adapter, a small framework run through /usr/bin/perl): the one source that still works on macOS 15.4 and later, where mediaremoted answers only entitled clients and nowplaying-cli gets null for everything. Nothing to install. The row is the app's name and icon (from its bundle id), the track and cover when the player reports them, and the position. The adapter runs as one long-lived child of pal (stream): every change the system reports lands in memory as it happens, so a look is microseconds and a track change reaches the bar at once.
  • Linux: playerctl over MPRIS, one row per player; the icon is the player's .desktop when one is named like it. Without playerctl the one row says to install it.

The bar item Now Playing puts the playing track on the strip (hidden while nothing plays, unless its paused rule or the core's show keeps it). Its popover is a card: the cover large at the left (the stream's picture; a cover the player names by url is fetched once into the picture, 2 MB at most; the app's own icon without one; a note tile without even that), the title, the artist and the album beside it with the player as a badge (and paused in amber), a progress row (the position, a bar, the duration) that ticks every second while the popover shows (the position moved along by the clock from the last look, no player asked), then the transport and the rest as keys, each a click too: space pause or play, left / right (or cmd+left / cmd+right) previous and next, c (or cmd+c) copy artist - title, o (or cmd+o) open the track in its player; a click on the cover or the titles opens it too. A player that names no track (a browser) shows its app as the title and the position. The core asks for the item every 30 s, on show and wake, and, on macOS, the moment the stream sees the track, the state or the cover change (the media trigger). Without that stream (Linux) the extension looks at the players itself every 5 s while one was playing at the last look and pushes when the track or the state changed, so a skip shows within seconds and an idle machine costs nothing.

What it does not do

  • Seek, shuffle, repeat or volume: the capability has play, pause, next and previous.
  • Launch a player: a player that is not running is not listed, and nothing here starts one.
  • Show a queue or a playlist; one row per player, the current track only.
  • Artwork for Music on macOS from Music itself: Music gives no url; the row shows the system's cover for it while the system reports one, else the app's icon.
  • Tick the position while the palette stays open: the row is what the core estimated when the list was made; the next show has the new one.

Platforms

macOS and Linux. macOS needs the Automation permission for Spotify and Music (asked once per app); anything else comes through the bundled MediaRemote adapter. Linux needs playerctl.