Hi there - I'm developing an app utilizing MusicKit and I frequently update the queue with new entries while the playlist is currently playing.
Occasionally I see this message in the console: [Playback] Inserting entries at the beginning of the queue because previous entry (MusicPlayer.Queue.Entry(id: "4B9D0B42-95E4-4F4C-B9A2-7D25F0BB4971", transientItem: Song(id: "1089596553", title: "Twin Turbo", artistName: "Sensible Soccers"))) is unexpectedly transient: [MusicPlayer.Queue.Entry(id: "21B1233B-44ED-48AE-9739-6045AF5FE170", transientItem: Song(id: "1607400995", title: "Don't Be Afraid (feat. Jungle)", artistName: "Diplo & Damian Lazarus"))]
What does this mean? What can I do to prevent it from happening?
Hello @nickfromsf,
I was able to reproduce this exact scenario with the following code:
let songsRequest = MusicCatalogResourceRequest<Song>(matching: \.id, memberOf: ["1089596553", "1607400995"])
let songsResponse = try await songsRequest.response()
let twinTurboSong = songsResponse.items[0]
let dontBeAfraidSong = songsResponse.items[1]
let queue = ApplicationMusicPlayer.shared.queue
queue.entries.insert(MusicPlayer.Queue.Entry(twinTurboSong), at: 1)
DispatchQueue.main.async {
queue.entries.insert(MusicPlayer.Queue.Entry(dontBeAfraidSong), at: 2)
}
ApplicationMusicPlayer's Queue maintains a collection of Entries that can be mutated by the application, and that get automatically updated under the hood when the state of the playback engine's queue changes.
When this code inserts twinTurboSong
, the entry being inserted is transient, indicating that it hasn't been fully inserted in the playback queue; hence, it has a temporary identifier; this entry remains transient until ApplicationMusicPlayer gets notified by the playback engine of the new state of the queue, with all inserted entries fully resolved.
This resolution process is especially important for collections such as album or playlists; you could insert a MusicPlayer.Queue.Entry with an Album; when you do, the playback engine will asynchronously resolve the tracks of the album, and the transient entry with an album will get replaced with regular entries for each track.
Back to this snippet of code, by inserting dontBeAfraidSong
in the next turn of the main thread runloop, we're making it extremely likely that the playback engine hasn't had sufficient time to perform this resolution process for the previously inserted entry, the one for twinTurboSong
.
I suppose you could avoid inserting new entries right after an existing Entry that has isTransient set to true
.
But I don't think that's a satisfactory answer. I think you should just file a ticket on Feedback Assistant describing to the best ability what you're doing as a user of your app to get in this situation. This information will allow us to have a clear picture of the user impact of this issue.
Thank you very much in advance for your help.
Best regards,