Fahad Jamal
Fahad Jamal

Reputation: 341

importing song as mp3 from the ipod music library to the App

I am making an audio app. In which I have pick a song from iPhone device audio library then I want to save it to my app document folder as in mp3 format. i tired alot of codes, but they import the file in m4a format, and when i rename it to mp3, the album art and all the meta data vanished from the file.i used the below code , but it import the file as in m4a format.

NSString *songTitle = [item valueForProperty:MPMediaItemPropertyTitle];
NSString *artist = [item valueForProperty:MPMediaItemPropertyArtist];
NSString *album = [item valueForProperty:MPMediaItemPropertyAlbumTitle];
MPMediaItemArtwork *artwork = [item valueForProperty:MPMediaItemPropertyArtwork];
UIImage *artworkImage = [artwork imageWithSize:CGSizeMake(250.00, 250.00)];
AVMutableMetadataItem *artistMetadata = [[AVMutableMetadataItem alloc] init];
artistMetadata.key = AVMetadataiTunesMetadataKeyArtist;
artistMetadata.keySpace = AVMetadataKeySpaceiTunes;
artistMetadata.locale = [NSLocale currentLocale];
artistMetadata.value = artist;

AVMutableMetadataItem *albumMetadata = [[AVMutableMetadataItem alloc] init];
    albumMetadata.key = AVMetadataiTunesMetadataKeyAlbum;
    albumMetadata.keySpace = AVMetadataKeySpaceiTunes;
    albumMetadata.locale = [NSLocale currentLocale];
    albumMetadata.value = album;

    AVMutableMetadataItem *songMetadata = [[AVMutableMetadataItem alloc] init];
    songMetadata.key = AVMetadataiTunesMetadataKeySongName;
    songMetadata.keySpace = AVMetadataKeySpaceiTunes;
    songMetadata.locale = [NSLocale currentLocale];
    songMetadata.value = songTitle;

    AVMutableMetadataItem *imageMetadata = [[AVMutableMetadataItem alloc] init];
    imageMetadata.key = AVMetadataiTunesMetadataKeyCoverArt;
    imageMetadata.keySpace = AVMetadataKeySpaceiTunes;
    imageMetadata.locale = [NSLocale currentLocale];
    imageMetadata.value = [NSData dataWithData:UIImagePNGRepresentation(artworkImage)]; //imageData is NSData of UIImage.

    NSArray *metadata = [NSArray arrayWithObjects:artistMetadata, albumMetadata, songMetadata, imageMetadata, nil];

    //convert MPMediaItem to AVURLAsset.
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    //get the extension of the file.
    NSString *fileType = [[[[assetURL absoluteString] componentsSeparatedByString:@"?"] objectAtIndex:0] pathExtension];

    //init export, here you must set "presentName" argument to "AVAssetExportPresetPassthrough". If not, you will can't export mp3 correct.
    AVAssetExportSession *export = [[AVAssetExportSession alloc] initWithAsset:songAsset
                                                                 presetName:AVAssetExportPresetPassthrough];

    NSLog(@"export.supportedFileTypes : %@",export.supportedFileTypes);
    //export to mov format.
    export.outputFileType = @"com.apple.quicktime-movie";
    export.metadata = metadata;

    NSString *extension = (__bridge  NSString *)UTTypeCopyPreferredTagWithClass((__bridge  CFStringRef)export.outputFileType, kUTTagClassFilenameExtension);

    NSLog(@"extension %@",extension);
    NSString *path = [NSString stringWithFormat:@"%@/%@.%@",self.folder.fullPath, songTitle, extension];

    NSURL *outputURL = [NSURL fileURLWithPath:path];
    export.outputURL = outputURL;
    [export exportAsynchronouslyWithCompletionHandler:^{
        if (export.status == AVAssetExportSessionStatusCompleted) {
        }
        else
        {
            NSLog(@"%@",export.error);
        }
    }];

Upvotes: 1

Views: 1487

Answers (1)

Nilesh Kikani
Nilesh Kikani

Reputation: 2618

You can import songs from iPod by using below code.

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

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

    [self exportAssetAsSourceFormat:[[mediaItemCollection items] objectAtIndex:i]];
    //NSLog(@"for loop : %d", i);
}
}

- (void)exportAssetAsSourceFormat:(MPMediaItem *)item {

NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];

BOOL isCloud = FALSE;

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    NSNumber *isCloudNumber = [item valueForProperty:MPMediaItemPropertyIsCloudItem];
    isCloud = [isCloudNumber boolValue];
}


if(assetURL != nil &&  ![assetURL isKindOfClass:[NSNull class]] && ! isCloud)
{
    NSLog(@"ASSET URL :%@ ", assetURL);

    NSLog(@"\n>>>> assetURL : %@",[assetURL absoluteString]);
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    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;

    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]];

    NSArray *fileNameArray = nil;
    fileNameArray = [fileName componentsSeparatedByString:@" "];
    fileName = [fileNameArray componentsJoinedByString:@""];

    NSString *docDir = [[AppDelegate sharedAppDelegate]applicationDocumentsDirectory];

    NSString *filePath = [[docDir stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:ex];

    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);
    }

    // -------------------------------------

    [self deleteMyFile:filePath];
    filePath = [filePath stringByAppendingString:@".mov"];
    [self deleteMyFile:filePath];

    exportSession.outputURL = [NSURL fileURLWithPath:filePath];

    [exportSession exportAsynchronouslyWithCompletionHandler:^{

        if (exportSession.status == AVAssetExportSessionStatusCompleted) {

            NSFileManager *fileMgr = [NSFileManager defaultManager];
            NSError *error;
            NSString *newpath = [filePath stringByReplacingOccurrencesOfString:@".mov" withString:@""];
            if ([fileMgr moveItemAtPath:filePath toPath:newpath error:&error] != YES)
                NSLog(@"Unable to move file: %@", [error localizedDescription]);
                            }
        }
        else
        {
            //NSLog(@"export session error");
        }
        [exportSession release];
    }];

}   

}

-(void)deleteMyFile:(NSString *)path
{

    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSError *deleteErr = nil;
        [[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
        if (deleteErr) {
            NSLog (@"Can't delete %@: %@", path, deleteErr);
        }
    }
}

Let me know if you have any other query related to this code.

Upvotes: 3

Related Questions