I am using MusicKit ApplicationMusicPlayer
to play music in my app. Everything works fine as long as I’m not playing large playlists that contain hundreds of songs. When I try to play a collection of songs that is larger than around 300 I’m always getting the error message saying:
"Prepare to play failed" UserInfo={NSDebugDescription=Prepare to play
failed, NSUnderlyingError=0x121d42dc0 {Error
Domain=MPMusicPlayerControllerErrorDomain Code=9 "Remote call timed
out" UserInfo={NSDebugDescription=Remote call timed out}}}))
It doesn’t matter if songs are downloaded to the device or not.
I am aware that there is another initializer for player’s queue that accepts Playlist
instances but in my app users can choose to sort playlist tracks in different order than the default and that makes using that initializer not feasible for me.
I tried everything I could think of, I tried to fall back on MPMusicPlayerController
and pass array of MPMusicPlayerPlayParameters
to it but the result was the same.
typealias QueueEntry = ApplicationMusicPlayer.Queue.Entry
let player = ApplicationMusicPlayer.shared
let entries: [QueueEntry] = tracks
.compactMap {
guard let song = $0 as? Song else { return nil }
return QueueEntry(song)
}
Task(priority: .high) { [player] in
do {
player.queue = .init(entries, startingAt: nil)
try await player.play() // prepareToPlay failed
} catch {
print(error)
}
}
2
Answers
Seems to be a limitation that other devs have experienced.
Rudrank Riyam has written a lot about using MusicKit, and he even posted on Twitter about your exact problem.
https://twitter.com/rudrankriyam/status/1758035733124722850
What is the use-case for a playlist of hundreds of items though?
I faced the exact problem last year when I had to deal with playlists, and as Ben mentioned, it does not work well for items over > 150.
My workaround was adding 100 songs and playing them. Then, after a delay (1 to 1.5 seconds), add 100 more songs to the queue, and repeat it until all the songs are added to the queue. That works, a bad workaround, but it works.