EMB / ege-mert-balcik

Why Mac now-playing apps stopped working in macOS 15.4

By Ege Mert Balçık · Last updated 3 November 2026 · Disclosure: I make Ledge, one of the apps that uses the workaround described here

Short answer: Mac apps that show what is playing usually read it from MediaRemote, a private Apple framework. Starting with macOS 15.4, the daemon behind it answers requests for the current track only from processes whose bundle identifier begins with com.apple., so an ordinary app gets nothing back. Play, pause and skip commands still go through. The common fix runs a small helper inside Apple's signed /usr/bin/perl, which macOS identifies as com.apple.perl; the open-source mediaremote-adapter packages this. The other route asks Music and Spotify directly with AppleScript, which reaches only apps that are scriptable. The perl route rests on behaviour Apple does not document, so a later macOS update can break it again.

What MediaRemote is

MediaRemote is the private framework macOS uses to keep track of what is playing across apps. Players that publish their track to the system show up in it, whether that is Music, Spotify, a YouTube tab or VLC, so one query returns the title, artist, artwork and position of whatever is playing. Apple has never offered it as a public API. Developers found its functions anyway, such as MRMediaRemoteGetNowPlayingInfo to read the current track and MRMediaRemoteSendCommand to play, pause or skip. Lyrics apps, Discord status apps, menu bar tools and notch apps used them.

What changed in macOS 15.4

Reports began during the 15.4 betas in February 2025 and kept coming after the release. The symptom was the same everywhere: the app could still pause and skip, while the track, artwork and progress bar were gone. In boring.notch's issue, a user on version 2.6 wrote that the next, previous and pause controls worked but "the music slider, album poster is not showing". Lyric Fever's tracker has the same finding at the code level: MRMediaRemoteGetNowPlayingInfo returns nil while MRMediaRemoteCommand still works.

In that Lyric Fever thread, the developer Mx-Iris traced it to the mediaremoted daemon, which in 15.4 began checking the entitlements of each client. The read entitlements (com.apple.mediaremote.now-playing-read-access and com.apple.mediaremote.full-now-playing-read-access) existed in earlier versions, which did not appear to check them. Later testing, written up in the mediaremote-adapter README, found that processes with a bundle identifier starting with com.apple. are let through. Ledge's source records the same result on macOS 26.4: called from Ledge itself the info dictionary comes back null, while called from inside perl it has every key. The newer MRNowPlayingRequest class is blocked in the same way when an app calls it directly.

Which apps broke

AppWhat its tracker saysHow it came back
boring.notch (notch app)Issue #417, March 2025: "Now Playing no longer working after updating to MacOS 15.4"v2.7 RC 0, July 2025: separate controllers for Spotify, Apple Music and YouTube Music, plus MediaRemote again through mediaremote-adapter, credited in its README
Music Presence (Discord status)Issue #165, February 2025: "Non-functional on macOS 15.4"2.3.1, June 2025: "media detection is fixed across the board for all versions of macOS (even 15.4 and above)", using mediaremote-adapter
MediaMate (HUDs and now playing)3.7.0 release notes, April 2025: macOS 15.4 "restricted some APIs that MediaMate relied on"Same release: "another API" restores Apple Music and Spotify; the "Allowed apps" setting was removed
nowplaying-cli (command line)Issue #28, April 2025: "nowplaying-cli no longer works on macOS 15.4"2.0.0, April 2026: "Restore support for macOS 15 and macOS 26", with code adapted from mediaremote-adapter
Lyric Fever (menu bar lyrics)Issue #94, March 2025: "MRMediaRemoteGetNowPlayingInfo return nil in latest MacOS"Issue still open when I checked
SketchyBar (menu bar)Issue #708, April 2025: "media_change event not firing", reported after updating to 15.4Issue still open when I checked

The mediaremote-adapter README keeps a longer list of these reports.

The perl workaround

mediaremote-adapter is a BSD-3-Clause project by Jonas van den Berg, who also makes Music Presence. Its README describes the method in one line: use a system binary, /usr/bin/perl, "which is entitled to use the MediaRemote framework" and have it dynamically load a custom helper framework "that prints real-time updates to stdout". An app bundles the Perl script and the framework without linking against it, starts /usr/bin/perl with both and reads the JSON it prints. Because the code runs inside perl, mediaremoted sees a client named after perl; the README shows a Console line with bundleIdentifier = com.apple.perl5.

The same script can also send commands, seek and set shuffle, repeat or playback speed. Its test command briefly simulates playback to check that reading still works, so an app can "fall back to other methods for media detection (e.g. AppleScript)" when it stops. The README warns that the test can make a fake entry appear as the now playing app for a moment. It also says the project "is still in development and the API may experience breaking changes across minor revisions". For Swift projects it points to a maintained fork packaged as a Swift package. To watch it work, the same author's media-control installs with brew tap ungive/media-control and brew install media-control. After that, media-control stream prints every change.

The README also lists a lighter route that runs MRNowPlayingRequest through osascript, another Apple binary. It is simpler to build, though "unable to load the song artwork" and unable to deliver real-time updates.

Per-app scripting instead

The older route skips MediaRemote and asks each player. Music and Spotify each ship a scripting dictionary, which you can open from Script Editor's library, with the current track, player state and player position along with play, pause and skip commands. An app runs a short AppleScript against each player. The first time, macOS asks whether the app may control Music or Spotify. You can change the answer later in System Settings > Privacy & Security > Automation.

Only apps with a dictionary can be asked. Ledge's scripting code notes that audio playing in a browser is invisible to it, so YouTube and other web players drop out. If you decline the Automation prompt, the app sees nothing from that player. AppleScript only answers when asked, so apps poll. Each read is a fresh query (through osascript, a new process every time). Artwork differs between the two players. Spotify's dictionary has an artwork URL; Music's gives the raw image data and no URL. Lyric Fever's 3.2 release notes call its Apple Music artwork workaround "buggy" and hope "Apple fixes AppleScript support in 26.1".

The risks

The perl route rests on undocumented behaviour, which is how the old direct route ended in 15.4. It needs three things to stay true at once. mediaremoted has to keep letting com.apple. identifiers through. perl's signature has to keep allowing it to load a library Apple did not sign. And /usr/bin/perl has to keep shipping. On the last point, Apple's macOS Catalina 10.15 release notes say, under deprecations, that Python, Ruby and Perl are included "for compatibility with legacy software" and that "Future versions of macOS won't include scripting language runtimes by default". The mediaremote-adapter test command exists because, in its README's words, "future macOS updates may break MediaRemote access again". Scripting is a public interface, though it can still shift under an app, as Lyric Fever's Music artwork workaround shows.

There is also the question of trust. The helper runs inside a program Apple ships. What it does there is up to the app. mediaremote-adapter and the Ledge library below are both open source, so you can read what gets loaded; with a closed-source app you take the developer's word for it.

What Ledge does

Ledge (mine; free, GPL-3.0, for notched MacBooks on macOS 26) takes the perl route with a small library of its own. In version 1.2.5 that library is plain Objective-C, exports one symbol and only reports what is playing; perl loads it through its built-in DynaLoader. The README says plainly that this is "software that can break on any macOS update". Every private symbol is looked up at runtime and checked, so a removed one turns the feature off without crashing the app.

Even with the helper running, Ledge reads Music and Spotify through AppleScript (once you grant Automation) and uses the helper to notice them and to show everything else, such as a browser tab. If the helper goes quiet while AppleScript can see a track playing, Ledge sets it aside for up to two minutes and keeps checking whether it has come back. When perl is missing the source tries /usr/bin/ruby with the same library. When neither works, Ledge falls back to AppleScript alone, which covers Music and Spotify. Ledge cannot help on an external display or on anything before macOS 26. boring.notch, Music Presence and MediaMate are the ones to look at there.

Which to choose

FAQ

Why does my Mac menu bar or notch app no longer show what is playing?

Since macOS 15.4 the private MediaRemote framework gives ordinary apps no track information, although play, pause and skip still work. An app without a workaround shows its controls with no title or artwork. Update the app and read its release notes.

What is mediaremote-adapter?

An open-source project (BSD-3-Clause) that reads now-playing information on macOS 15.4 and later by running a helper inside Apple's signed /usr/bin/perl, which MediaRemote still answers. boring.notch, Music Presence and the media-control command-line tool use it.

Can AppleScript replace MediaRemote?

For Music and Spotify, largely. Both have a scripting dictionary with the current track, player state and position, so an app can read them once you allow it under Privacy & Security > Automation. Media playing in a browser tab is not exposed that way.

Will the perl workaround keep working?

Nobody outside Apple can promise that. It depends on undocumented behaviour. Apple also said in the macOS Catalina release notes that future versions of macOS will not include scripting runtimes such as Perl by default. Apps that use it should check at launch that it still works and fall back to AppleScript when it does not.

Related

Sources