将歌曲作为mp3从ipod音乐库导入App

时间:2015-03-05 05:29:16

标签: ios objective-c iphone avassetwriter

我正在制作音频应用。我从iPhone设备音频库中选择了一首歌,然后我想将它保存到我的应用文档文件夹,如mp3格式。我厌倦了很多代码,但他们以m4a格式导入文件,当我将其重命名为mp3时,专辑封面和所有元数据从file.i中消失,使用下面的代码,但它导入文件,如m4a格式。

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

1 个答案:

答案 0 :(得分:2)

您可以使用以下代码从iPod导入歌曲。

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

如果您有与此代码相关的任何其他查询,请与我们联系。