Question

Hello i am using below framworks,

#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

In one of button event i have implemented below code to open Library.

        MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
    mediaPicker.delegate = self;
    mediaPicker.allowsPickingMultipleItems = YES; // this is the default   
    [self presentModalViewController:mediaPicker animated:YES];
    [mediaPicker release];

And in delegate methods of MPMediaPickerController implemented code as below

#pragma mark MPMediaPickerController delegate methods

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

    // We need to dismiss the picker
    [self dismissModalViewControllerAnimated:YES];

    // Assign the selected item(s) to the music player and start playback.

    counterIpod = [mediaItemCollection.items count];
    totalcollection = counterIpod;
    if (totalcollection > 10) {
        NSString *str = [NSString stringWithFormat:@"App Only supports importing 10 songs at a time"];
        UIAlertView *connectionAlert = [[UIAlertView alloc] initWithTitle:@"Message !" message:str delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [connectionAlert show];
        [connectionAlert release];
    }
    else {
        [self performSelector:@selector(saveMediaItem:) withObject:mediaItemCollection afterDelay:0.1];
        //[self saveMediaItem:mediaItemCollection];
        //[self showLoadingView];       
    }
}

- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
    // User did not select anything
    // We need to dismiss the picker
    [self dismissModalViewControllerAnimated:YES];
}

#pragma mark Sace Item Collection to documentsDirectory
-(void)saveMediaItem:(MPMediaItemCollection *)mediaItemCollection {

    for (int i = 0; i < [mediaItemCollection.items count]; i++) {

        [self exportAssetAsSourceFormat:[[mediaItemCollection items] objectAtIndex:i]];

        NSLog(@"for loop : %d", i);
    }

    NSArray *itemsArray1 = appDelegate.mediaItemCollection1.items;
    MPMediaItemCollection *mediaItemCollection2;

    if ([itemsArray1 count] != 0) {
        mediaItemCollection2 = [self collectionByAppendingCollection:mediaItemCollection];
    }
    else {
        mediaItemCollection2 = mediaItemCollection;
    }

    [self saveMediaItemAfterDeletting:mediaItemCollection2];
}

-(void)saveMediaItemAfterDeletting:(MPMediaItemCollection *)mediaItemCollection {

    NSMutableData* data = [[NSMutableData alloc] init];

    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:mediaItemCollection forKey:@"my_playlist"];
    [archiver finishEncoding];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *filePath = [NSString stringWithFormat:@"%@/playlist.data", documentsDirectory];
    NSLog(@"file path = %@", filePath);

    [data writeToFile:filePath atomically:YES];

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
        NSLog(@"file exists : ===========>>>>>>>>>>>");
    } else {
        NSLog(@"file doesn't exist");
    }

    //NSLog(@"archiving playlist success = %d", success);

    [archiver release];
    [data release];

    [self UpdateMediaCollection];
}

-(NSString*) getExtension:(MPMediaItem *)item {

    //  [self showLoadingView];

    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    // JP
//  AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
//                                         initWithAsset:songAsset
//                                         presetName:AVAssetExportPresetPassthrough];

    NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *track = [tracks objectAtIndex:0];

    id desc = [track.formatDescriptions objectAtIndex:0];
    const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
    FourCharCode formatID = audioDesc->mFormatID;

    //exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters]; 
    //exportSession.audioMix = exportAudioMix;

    NSString *fileType = nil;
    NSString *ex = nil;

    switch (formatID) {

        case kAudioFormatLinearPCM:
        {
            UInt32 flags = audioDesc->mFormatFlags;
            if (flags & kAudioFormatFlagIsBigEndian) {
                fileType = @"public.aiff-audio";
                ex = @"aif";
            } else {
                fileType = @"com.microsoft.waveform-audio";
                ex = @"wav";
            }
        }
            break;

        case kAudioFormatMPEGLayer3:
            fileType = @"com.apple.quicktime-movie";
            ex = @"mp3";
            break;

        case kAudioFormatMPEG4AAC:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        case kAudioFormatAppleLossless:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        default:
            break;
    }   

    return ex;

}


#pragma mark Covert Item separate item collection and store songs into directory 
- (void)exportAssetAsSourceFormat:(MPMediaItem *)item {

    //  [self showLoadingView];

    NSLog(@"export asset called");
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    NSLog(@"\n>>>> assetURL : %@",[assetURL absoluteString]);
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    // JP
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
                                           initWithAsset:songAsset
                                           presetName:AVAssetExportPresetPassthrough];

    NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *track = [tracks objectAtIndex:0];

    id desc = [track.formatDescriptions objectAtIndex:0];
    const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
    FourCharCode formatID = audioDesc->mFormatID;

    //exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters]; 
    //exportSession.audioMix = exportAudioMix;

    NSString *fileType = nil;
    NSString *ex = nil;

    switch (formatID) {

        case kAudioFormatLinearPCM:
        {
            UInt32 flags = audioDesc->mFormatFlags;
            if (flags & kAudioFormatFlagIsBigEndian) {
                fileType = @"public.aiff-audio";
                ex = @"aif";
            } else {
                fileType = @"com.microsoft.waveform-audio";
                ex = @"wav";
            }
        }
            break;

        case kAudioFormatMPEGLayer3:
            fileType = @"com.apple.quicktime-movie";
            ex = @"mp3";
            break;

        case kAudioFormatMPEG4AAC:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        case kAudioFormatAppleLossless:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        default:
            break;
    }

    exportSession.outputFileType = fileType;     

    NSString *fileName = nil;

    fileName = [NSString stringWithString:[item valueForProperty:MPMediaItemPropertyTitle]];
    fileName = [[fileName stringByAppendingString:@"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];
    NSArray *fileNameArray = nil;
    fileNameArray = [fileName componentsSeparatedByString:@" "];
    fileName = [fileNameArray componentsJoinedByString:@""];

    NSLog(@">>>>> fileName = %@", fileName);

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath = [[docDir stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:ex];

    NSLog(@"filePath = %@", filePath);  

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        //NSLog(@"file exist::::::::::==============>>>>>>>>>>>>>>>>>");
        counterIpod--;

        if(counterIpod == 0) {
            //[self showAlertView];
            //[self hideLoadingView];
        }

        NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
        [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
        //NSLog(@"loading string : %@", str);

        return;
    }

    //NSLog(@"file not exist  ===========>>>>>>>>>");
    // -------------------------------------
    int fileNumber = 0;
    NSString *fileNumberString = nil;
    NSString *fileNameWithNumber = nil;
    while ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        fileNumber++;
        fileNumberString = [NSString stringWithFormat:@"-%02d", fileNumber];
        fileNameWithNumber = [fileName stringByAppendingString:fileNumberString];
        filePath = [[docDir stringByAppendingPathComponent:fileNameWithNumber] stringByAppendingPathExtension:ex];
        //NSLog(@"filePath = %@", filePath);        
    }   

    // -------------------------------------    
    myDeleteFile(filePath);
    exportSession.outputURL = [NSURL fileURLWithPath:filePath];

    [exportSession exportAsynchronouslyWithCompletionHandler:^{

        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"export session completed");
            counterIpod--;

            NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];

            //[self performSelector:@selector(setLabelText:) withObject:str afterDelay:0.02];
            [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
            NSLog(@"loading string : %@", str);

            if(counterIpod == 0) {
                //[self showAlertView];
                //[self hideLoadingView];
            }
        } else {
            NSLog(@"export session error");
            counterIpod--;
            NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
            [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
            //return NO;
            if(counterIpod == 0) {
                //[self showAlertView];
                //[self hideLoadingView];
            }
        }

        [exportSession release];
    }];

    //[appDelegate hideLoadingView];
}

#pragma mark method to delete file from document directory 
void myDeleteFile (NSString* path) {
    //  NSLog(@"file path delete file :::::::::: %@", path);
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSError *deleteErr = nil;
        [[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
        if (deleteErr) {
            NSLog (@"Can't delete %@: %@", path, deleteErr);
        }
    }
}

Above code work without any error on iOS 4.0 or prior version but for iOS 5.0 is crashes on device, I can't resolve these issues since last 15 days.

Thanks in advance for Help.

Was it helpful?

Solution

I have solved this issues,

just comment out this line

 fileName = [[fileName stringByAppendingString:@"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];

because for some songs there is null artist so it's crash...................

OTHER TIPS

This is because you are using some songs has artist name while some with blank artist name, so you are trying to append blank name in string that's why app going to crash.

Hope you unserstand what i say...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top