Can't set MPMusicPlayerController queue with MPMusicPlayerMediaItemQueueDescriptor

夙愿已清 提交于 2019-12-02 16:28:16

问题


This code results in silence:

let query = MPMediaQuery.songs()
let result = query.items
guard let items = result, items.count > 0 else {return}
let song = items[0]

let player = MPMusicPlayerController.applicationQueuePlayer

let coll = MPMediaItemCollection(items: [song])
let q = MPMusicPlayerMediaItemQueueDescriptor(itemCollection: coll)
player.setQueue(with: q)
player.play()

I've stepped through the code, and we reach player.play(). I have an MPMediaItem and I've correctly formed an MPMediaItemCollection from that, and an MPMusicPlayerMediaItemQueueDescriptor from that. So why isn't my player playing?


回答1:


You've found a bug. It appears that the initializer MPMusicPlayerMediaItemQueueDescriptor(itemCollection:) is completely broken: it results in an unusable queue descriptor.

The workaround, where possible, is to use the other initializer instead, namely MPMusicPlayerMediaItemQueueDescriptor(query:).

For example, in this case, you could write (picking up in the last four lines of the original code):

let coll = MPMediaItemCollection(items: [song])
let predicate = MPMediaPropertyPredicate(
                value: song.persistentID,
                forProperty: MPMediaItemPropertyPersistentID)
let query = MPMediaQuery(filterPredicates: [predicate])
let q = MPMusicPlayerMediaItemQueueDescriptor(query: query)
player.setQueue(with: q)
player.play()

Unfortunately, there are many circumstances where you can't form a single query that gets the MPMediaItemCollection you really wanted.

In this particular example you could work around that, too, by setting the player's queue directly with an MPMediaItemCollection instead of a MPMusicPlayerMediaItemQueueDescriptor made from an MPMediaItemCollection.

But alas, there are some commands (such as append(_:)) that require an MPMusicPlayerMediaItemQueueDescriptor, and for things like that, this entire API is basically hosed. It has been hosed since iOS 10.1 and it remains hosed in iOS 11.1.




回答2:


"It has been hosed since iOS 10.1 and it remains hosed in iOS 11.1." Seconded.

I have been in the midst of a protracted fight just trying to a) get MPMusicPlayerController to simply work (finally managed that) and b) get it to play a song from an offset (still have not). And this is in an app that prior to iOS 10 worked 100% as expected.

Right now, this is code that works for me (at least with regard to getting a song to play):

let currentPlayer = MPMusicPlayerController.applicationQueuePlayer()
currentPlayer.repeatMode = .none

self.currentCollection = MPMediaItemCollection(items: [mediaItem])
currentPlayer.beginGeneratingPlaybackNotifications()

let query = MPMediaQuery.songs()
let pred = MPMediaPropertyPredicate(value: mediaItem.persistentID, forProperty: MPMediaItemPropertyPersistentID)
query.addFilterPredicate(pred)
let desc = MPMusicPlayerMediaItemQueueDescriptor(query: query)
currentPlayer.setQueueWith(desc)

currentPlayer.prepareToPlay(completionHandler: {[unowned self] (error) in
    MPMusicPlayerController.applicationQueuePlayer().play()
})

It is a bit convoluted in that I had to use what I would consider the most complicated means based on available APIs. But several other methods cause the completion block to either never get called or get a completely unhelpful error. Right now I have 5 bugs reported to Apple with regard to MPMusicPlayerController so I am not exactly a happy developer at the moment. I will be opening one more related to this code as setStartTime & setEndTime does not appear to work any better than currentPlaybackTime for starting play at a specified offset.

This code does dependably play synced and downloaded Apple Music items though.



来源:https://stackoverflow.com/questions/46836728/cant-set-mpmusicplayercontroller-queue-with-mpmusicplayermediaitemqueuedescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!