Search code examples
iosavfoundationmpmusicplayercontrollermpmediaitemmpmediaitemcollection

Play an MPMediaItemCollection in MPMusicPlayerController shuffled, but let user choose the first item?


I'm working on an application that integrates with the iPod Music app on iOS. It displays different music groupings (i.e., MPMediaItemCollections) and it allows the user to play these groupings in the Music app, using [MPMusicPlayerController ipodMusicPlayer].

My issue is that I'm having difficulty getting shuffle functionality working the same way between my app and the music app. When I play a song, I call:

MPMusicPlayerController* musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
[musicPlayer stop];
MPMediaItemCollection* collection = [self.displayedContainerGroup getMediaItemCollection];
[musicPlayer setQueueWithItemCollection:collection];
[musicPlayer setNowPlayingItem:[container getMediaItem];
[musicPlayer play];

This works great if shuffle is turned off. If the user selects a song (which is part of an album), this plays the album in the music app and starts on the specified song.

If shuffle is turned on, though, what this appears to do is shuffle the songs first, and then jumps to the new nowPlayingItem in the order that they were just shuffled in. The problem with this is that unless the nowPlayingItem was shuffled to first in order, it doensn't end up playing all the songs in the album.

The MPMusicPlayerController documentation says about nowPlayingItem: "To specify that playback should begin at a particular media item in the playback queue, set this property to that item while the music player is stopped or paused."

So, I'm wondering if there's a way to make this work for shuffle mode - start on one user-selected song in an album, and then play all the rest of the songs shuffled. Or should I just create a custom MPMediaItemCollection and shuffle it myself for this?


Solution

  • This seems to have worked; I had to turn off shuffle, add the songs, switch to the now playing item, and then turn shuffle back on:

    [musicPlayer stop];
    BOOL shuffleWasOn = NO;
    if (musicPlayer.shuffleMode != MPMusicShuffleModeOff)
    {
         musicPlayer.shuffleMode = MPMusicShuffleModeOff;
         shuffleWasOn = YES;
    }
    [musicPlayer setQueueWithItemCollection:mediaItemCollectionIn];
    [musicPlayer setNowPlayingItem:mediaItemIn];
    if (shuffleWasOn)
         musicPlayer.shuffleMode = MPMusicShuffleModeSongs;
    
    [musicPlayer play];