0

I want to get the queue from the Media Player. I believe that I can't read the queue though (is this correct?) and that I can only get the queue when I set it, like when I select a certain playlist to play. However I'm struggling to get the shuffled queue.

            let musicPlayerController = MPMusicPlayerController.systemMusicPlayer
            let myMediaQuery = MPMediaQuery.songs()
            let predicateFilter = MPMediaPropertyPredicate(value: chosenPlaylist, forProperty: MPMediaPlaylistPropertyName)
            myMediaQuery.filterPredicates = NSSet(object: predicateFilter) as? Set<MPMediaPredicate>
            musicPlayerController.setQueue(with: myMediaQuery)
            musicPlayerController.repeatMode = .all
            musicPlayerController.shuffleMode = .songs
            musicPlayerController.play()
            for track in myMediaQuery.items! {
                print(track.value(forProperty: MPMediaItemPropertyTitle)!)
            } // here I don't get the shuffled order that is going to play, just get the original order of the playlist

I need the shuffled as I want to be able to display what's going to play next.

Jack Vanderpump
  • 216
  • 2
  • 16
  • 1
    The MPMusicPlayerController queue allows itself to be set, but not accessed. You can loop through the mediaItemCollection in mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection), then add each item to an array of MPMediaItem, then use it to display the next song. I think shuffling only impacts play order, not the actual queue - you may have to capture the mediaItemCollection, assign it to a variable, randomize it, then set the queue using that randomized variable, and keep shuffle actually turned off so you know the 'random' order. – developingbassist Mar 02 '20 at 21:55
  • I'm thinking I'll have to shuffle myself and just capture the shuffle then, but if I can use the .shufflemode option that would be preferable – Jack Vanderpump Mar 02 '20 at 22:04
  • Agreed, MPMusicPlayerController is tricky to work with. Best of luck, I hope it works out. – developingbassist Mar 02 '20 at 22:12

1 Answers1

2

I've had trouble with .shuffleMode in the past. Call shuffled() on the collection instead:

// shuffle
func shufflePlaylist() {

    let query = MPMediaQuery.songs()
    let predicate = MPMediaPropertyPredicate(value: "Art Conspiracy",
                                             forProperty: MPMediaPlaylistPropertyName,
                                             comparisonType: .equalTo)
    query.addFilterPredicate(predicate)

    guard let items = query.items else { return }
    let collection = MPMediaItemCollection(items: items.shuffled())

    player.setQueue(with: collection)
    player.prepareToPlay()
    player.play()
}
Brian Hamm
  • 426
  • 3
  • 8
  • Perfect. Another silly workaround we have to do, because of the arbitrary things Apple makes available in MediaKit, but that's great! Cheers – Jack Vanderpump Mar 12 '20 at 15:10
  • Yeah. I stumbled across the issue in a previous version of Xcode, which was in beta at the time. I figured it was due to 'beta stuff' and would be fixed later, but it wasn't. So, I tried shuffling the collection itself, and voilà. Glad it was helpful. – Brian Hamm Mar 13 '20 at 04:18
  • This works fine for small arrays (few hundred songs). I'm trying to shuffle my entire library (19000 songs) and setting the queue by creating an MPMediaItemCollection like this takes about 5-6 seconds. Setting directly by MPMediaQuery is about 1 second. – jjjjjjjj Apr 18 '20 at 09:09