0

I'm working on an app written in Xamarin.iOS/Forms that plays music. We want to be able to control the playback of the song/songlist from within the app or from the now playing info center. Everything is working as expected except I have not been able to programmatically control the state of the play/pause button in the info center when the user presses play/pause from within the app. My understanding from several swift examples is that you should be able to set the state by setting MPNowPlayingInfo.PlaybackRate to 1.0d for playing or 0.0d for paused. Here is some code from the app.

When a new song starts I add the song using the following code:

_nowPlayingInfo = new MPNowPlayingInfo();
_nowPlayingInfo.Artist = songDetails.Artist;
_nowPlayingInfo.Title = songDetails.Title;
_nowPlayingInfo.PlaybackDuration = durationSeconds;
_nowPlayingInfo.PlaybackRate = 0.0d;
                
var data = NSData.FromUrl(new NSUrl(songDetails.Album2xUrl));
var image = new UIImage(data:data);
_nowPlayingInfo.Artwork = new MPMediaItemArtwork(image);

MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = _nowPlayingInfo;

Everything works as expected except the initial state of the play/pause button shows the pause button and with PlaybackRate set to 0.0d I expected it to show the play button.

As the song plays I update the using the following code:

_nowPlayingInfo.ElapsedPlaybackTime = elapsedSeconds;
MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = _nowPlayingInfo;

This works as expected.

When the play/pause state updates from within the app I try to update the play/pause button in info center using the following code: which I have found in numerous swift examples but this has not affect on the play/pause button:

if (isPlaying)
    _nowPlayingInfo.PlaybackRate = 1.0d;
else
    _nowPlayingInfo.PlaybackRate = 0.0d;

MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = _nowPlayingInfo;
Console.WriteLine($"---- {MPNowPlayingInfoCenter.DefaultCenter.NowPlaying.PlaybackRate}");

I can see from the console that PlaybackRate is set to the expected value but changing the value has not effect on the play/pause state in info center.

Has anyone else had this issue in Xamarin.iOS? Is there a different way to update the state of the play/pause button?

I'm using Xamarin.iOS Version: 16.1.1.27, Xcode 14.2, and testing on an iOS 16.3.1 device.

  • Here're some suggestions: 1.Per [MPNowPlayingPlaybackState](https://developer.apple.com/documentation/mediaplayer/mpnowplayingplaybackstate?language=objc) in Apple's doc, you can try to set `MPNowPlayingInfoCenter.defaultCenter.nowPlayingInfo = MPNowPlayingPlaybackStatePaused;`, for more details, you can refer to https://stackoverflow.com/a/73304047/9644964 and https://developer.apple.com/documentation/mediaplayer/mpnowplayinginfopropertyplaybackrate?language=objc. 2. You can try to upgrade your ` Xamarin.iOS Version` to the latest one. – Alexandar May - MSFT Feb 28 '23 at 09:16
  • @AlexandarMay-MSFT Thanks for the suggestions. In Xamarin.iOS MPNowPlayingPlaybackState is defined as an enum and NowPlayingInfo is a different type so I can't make that assignment. In Xamrin bindings the only property defined as a type MPNowPlayingPlaybackState is MPNowPlayingInfoCenter.PlaybackState but it has the [NoiOS] attribute so its excluded from Xamarin.iOS. Also tried updating to lates Xamarin.iOS with no affect. – Mark Reynolds Mar 01 '23 at 17:29

1 Answers1

1

The solution for my app was to call AVAudioEngine.Pause() and AVAudioEngine.StartAndReturnError() to pause and start playing of audio. This automatically updates the play/pause button state in Now Playing. Previously I was using AVAudioPlayerNode.Play() and AVAudioPlayerNode.Pause().