0
votes

I am using multiple AVAudioPlayer instances to play different music beds on a touch of a button (100 buttons - 100 different songs). I store the url to the resource in an xml file (e.g. ipod-library://item/item.m4a?id=-6327897134951324787) and I initialize an AVAudioPlayer with this url when I need to play the song.

Now the issue: If I load all 100 songs in a player, quit the application from Xcode (which in this case is similar to a crash - unexpected exit) and do it a couple of more times, the next time I start the app, the iPod library url's will not be valid anymore, thus I cannot play the songs. The music library has an issue with not closing the connection to its resources properly I assume.

The problem is that I cannot stop a user from throwing out the app from the background, thus killing all the connections to the music library. This issue is very complex. An interesting thing is, that whenever this happens, those files which were "killed" in my app don't play in the iPod library either, so something is going terribly wrong.

1

1 Answers

0
votes

I had a similar problem. But I used MPMusicPlayerController

I need to save the selected music info from music library to play later but I couldnt.

I store the music data in NSUserDefaults

Here is my code

- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
if (mediaItemCollection) {

    [appDel.musicPlayer setQueueWithItemCollection: mediaItemCollection];
    if ([mediaItemCollection count] >0) {
        [appDel.musicPlayer play];
    }
    NSArray* items = [mediaItemCollection items];
    NSMutableArray* listToSave = [[NSMutableArray alloc] initWithCapacity:0];
    for (MPMediaItem *mpItem in items) {
        NSNumber *persistentId = [mpItem valueForProperty:MPMediaItemPropertyPersistentID];
        [listToSave addObject:persistentId];
    }

    int songId = [[[NSUserDefaults standardUserDefaults] objectForKey:@"lastID"] intValue];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:listToSave];
    if (editting) {
        [[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString stringWithFormat:@"song%@",edittingSong.sqlId]];
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setObject:data forKey:[NSString stringWithFormat:@"song%d",songId+1]];
    }
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self updateMusicInfo];
}

[self dismissModalViewControllerAnimated: YES];
}

You can use any key you want.

To read the data and set the queue in player.

NSMutableArray *theList = [[NSMutableArray alloc] initWithCapacity:0];
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"song%@",edittingSong.sqlId]];

NSArray *decodedData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[theList addObjectsFromArray:decodedData];
NSMutableArray *allTheSongs = [[NSMutableArray alloc] initWithCapacity:0];
for (int i = 0; i < [theList count]; i++) {
    MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
    [songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:[theList objectAtIndex:i] forProperty:MPMediaItemPropertyPersistentID]];
     NSArray *songs = [songQuery items];
     [allTheSongs addObjectsFromArray: songs];
 }

  f ([allTheSongs count] >0) {
     MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
     [appDel.musicPlayer setQueueWithItemCollection:currentQueue];
     [appDel.musicPlayer play];
 }