Setting playbackRate in MusicKit for Swift (beta)

Hi!

I'm trying out the new MusicKit for Swift (iOS 15 beta). Really liking it! But I'm seeing a weird issue with setting state.playbackRate to anything other than 1.0 when playing.

The issue appears to be that the player keeps trying to reset itself to a playbackRate of 1.0. If I set it to 0.5 or 2.0 it still plays the track back at a playbackRate of 1.0. Strangely, about 5% of attempts to change it are actually successful on the ApplicationMusicPlayer. SystemMusicPlayer changes more reliably at maybe a 20% success rate, in my testing. It seems to be happening during/after preparing the track. If I swap out the player's queue while it's preparing to play, I can get it to reliably throw a prepareToPlay error and, upon doing so, it then accepts the playbackRate change to a non-1.0 value.

I've tried setting the playbackRate before playing, after playing, and even both! Through observing the playbackRate property I can see that my alterations seem to stick for maybe 0.5 sec as the track loads, then the rate changes back to 1.0 as the song begins to play.

I understand it's still in beta so if the answer is simply "wait for release" then that's fine! But I'd like to know if anyone has found a way to reliably alter the playbackRate, as I'm in the middle of scouting a new project that will depend on it.

Some detail into my setup: I'm doing this in the WWDC21 project UsingMusicKitToIntegrateWithAppleMusic (which didn't compile out of the box for me until I reworked some of it). My setup is: iPadOS 15 beta 5 (19a5318f) on an iPad Air 2. Xcode v13.0 beta 5 (13A5212g). MacOS Big Sur 11.4.

Thanks!

Accepted Reply

Hello @lonsInTheEther,

Thanks for your questions on how to set the playbackRate for MusicKit to a value other than 1.0.

One important thing to know about this topic is that the play() method on ApplicationMusicPlayer and SystemMusicPlayer will set the playback rate to 1.0.

So I think the recommended way to implement the functionality you want to build is to avoid calling play() at all when you want the playback rate to be different from 1.0. Instead, you could do something like this:

let musicPlayer = ApplicationMusicPlayer.shared
musicPlayer.queue = [album]
try await musicPlayer.prepareToPlay()
musicPlayer.state.playbackRate = 2.0

That said, upon investigating your question, we have found some issues internally with how the playback rate is handled in our underlying playback engine. We'll investigate these issue, and try to address them.

Thanks again for your valuable feedback.

Best regards,

  • Thanks for getting back!

    I did notice through swiftUI observation that the playbackRate was changing to 1.0 when calling play, but as you've likely noticed, even setting the playbackRate again after playing is still unreliable and it continues to try to revert back to 1.0. Further, simply calling prepareToPlay() followed by a playbackRate setting as you've suggested does not work reliably.

    Very glad to hear you've spotted some of the issues and are potentially working on a fix! Thanks!

Add a Comment

Replies

Hello @lonsInTheEther,

Thanks for your questions on how to set the playbackRate for MusicKit to a value other than 1.0.

One important thing to know about this topic is that the play() method on ApplicationMusicPlayer and SystemMusicPlayer will set the playback rate to 1.0.

So I think the recommended way to implement the functionality you want to build is to avoid calling play() at all when you want the playback rate to be different from 1.0. Instead, you could do something like this:

let musicPlayer = ApplicationMusicPlayer.shared
musicPlayer.queue = [album]
try await musicPlayer.prepareToPlay()
musicPlayer.state.playbackRate = 2.0

That said, upon investigating your question, we have found some issues internally with how the playback rate is handled in our underlying playback engine. We'll investigate these issue, and try to address them.

Thanks again for your valuable feedback.

Best regards,

  • Thanks for getting back!

    I did notice through swiftUI observation that the playbackRate was changing to 1.0 when calling play, but as you've likely noticed, even setting the playbackRate again after playing is still unreliable and it continues to try to revert back to 1.0. Further, simply calling prepareToPlay() followed by a playbackRate setting as you've suggested does not work reliably.

    Very glad to hear you've spotted some of the issues and are potentially working on a fix! Thanks!

Add a Comment