This code results in silence:
let query = MPMediaQuery.songs()
let result = query.items
guard let items = result, items.count > 0 else {return}
let song = ite
Swift 5
I am a little late to the show, but this is what I came up with. (I was trimming songs for playback with descriptors).
Make sure that you run every thing with Music Player on the Main Thread. If not you will run into weird bugs.
Getting a song by persistentId:
/// Retrieves a song in the MPMediaItem format using the persistentId passed.
/// - Parameter persistentID: (UInt64) The songs persistentId.
/// - Returns: (MPMediaItem?) Nil if not found other wise the MPMediaItem (song).
private static func getSong(forId persistentID: UInt64) -> MPMediaItem? {
let query = MPMediaQuery.songs()
let predicate = MPMediaPropertyPredicate(value: persistentID, forProperty: MPMediaItemPropertyPersistentID)
query.addFilterPredicate(predicate)
return query.items?.first
}
Playing a song by persistentId:
private var startTime: Double = 0
private var endTime: Double = 0
/// Plays the song with the identifier.
/// - Note: Trims song to start and end time.
/// - Parameter persistentId: (UInt64) The song persistent identifier.
private func play(forId persistentId: UInt64) {
DispatchQueue.main.async {
if let song = Self.getSong(forId: persistentId) {
let identifier = MPMediaItemPropertyPersistentID
let predicate = MPMediaPropertyPredicate(value: persistentId, forProperty: identifier)
let query = MPMediaQuery(filterPredicates: [predicate])
let descriptor = MPMusicPlayerMediaItemQueueDescriptor(query: query)
descriptor.setStartTime(self.startTime, for: song)
descriptor.setEndTime(self.endTime, for: song)
self.musicPlayer.setQueue(with: descriptor)
self.musicPlayer.prepareToPlay()
self.musicPlayer.repeatMode = .none
self.musicPlayer.play()
}
}
}
Also I found that the way I initialize my music controller is important:
private lazy var musicPlayer: MPMusicPlayerController = { MPMusicPlayerController.applicationQueuePlayer }()
Please note: Some of the code isn't drag and drop. You would need to define things like start and end time variables.