MacOS not responding to MPRemoteCommandCenter commands in the background
Asked Answered
D

1

6

I am writing an application for my own purposes that aims to get play pause events no matter what is going on in the system. I have gotten this much working

let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("Play Pause Command")
    return .success
}

commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("NextTrackCommand")
    return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("previousTrackCommand")
    return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("playCommand")
    return .success
}

MPNowPlayingInfoCenter.default().playbackState = .playing

Most of those methods are there because apparently you will not get any notifications without having nextTrackCommand or previousTrackCommand or playCommand implemented.

Anyways my one issue is that as soon as you open another application that uses audio these event handlers stop getting called and I cant find a way to detect and fix this.

I would normally try doing AVAudioSession things to state this as a background application however that does not seem to work. Any ideas on how I can get playpause events no matter what state the system is in?

I would like to be able to always listen for these events OR get an indication of when someone else has taken control of the audio? Perhaps even be able to re-subscribe to these play pause events.

Dermoid answered 18/4, 2020 at 21:13 Comment(2)
Do you want to make MPRemoteCommandCenter work in the background or are other ways to catch the event ok?Catchpole
Absolutely! Just want to catch play pause. Technically I am trying to get play pause events from headphones/AirPods but I dont see any API for that.Dermoid
Z
4

There's an internal queue in the system which contains all the audio event subscribers. Other applications get on top of it when you start using them.

I would like to be able to always listen for these events

There's no API for that but there's a dirty workaround. If I understand your issue correctly, this snippet:

    MPNowPlayingInfoCenter.default().playbackState = .paused
    MPNowPlayingInfoCenter.default().playbackState = .playing

must do the trick for you if you run it in a loop somewhere in your application.

Note that this is not 100% reliable because:

  1. If an event is generated before two subsequent playbackState state changes right after you've switched to a different application, it would still be catched by the application in the active window;
  2. If another application is doing the same thing, there would be a constant race condition in the queue, with unpredictable outcome.

References:

OR get an indication of when someone else has taken control of the audio

As far as I know there's no public API for this in macOS.

Zonate answered 26/4, 2020 at 14:53 Comment(4)
I am tempted to give you the bounty but I do believe this may be the best possible. This method seems to work to get remote control events to my app after Spotify has taken over them... however some apps like Zoom's audio process retain this no matter what. This technique does not allow you to regain control events while Zoom is on. Why? What have they done on their end? Does it care if you are actually playing audio?Dermoid
An observation is if you set zoom to play to speakers (even while AirPods are connected) you then can get the play pause events from the AirPods... I dont understand why this matters.Dermoid
Probably because they're doing the same thing :-( This is an arms race, a competition overrr the single shared system resource where all the competitors have the same rights. See the bug report for mpv which has covered this topic in a great style: github.com/mpv-player/mpv/issues/4834 (I updated the answer with this link).Zonate
"Does it care if you are actually playing audio". To date, there's no practical evidence showing that it does.Zonate

© 2022 - 2024 — McMap. All rights reserved.