ios - 将歌曲作为 mp3 从 ipod 音乐库导入应用程序

标签 ios objective-c iphone avassetwriter

我正在制作一个音频应用。我从 iPhone 设备音频库中选择了一首歌曲,然后我想将它以 mp3 格式保存到我的应用程序文档文件夹中。我厌倦了很多代码,但它们以 m4a 格式导入文件,当我将其重命名为 mp3 时,专辑封面和所有元数据从文件中消失了。我使用了下面的代码,但它以 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);
        }
    }];

最佳答案

您可以使用以下代码从 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);
        }
    }
}

如果您有与此代码相关的任何其他疑问,请告诉我。

关于ios - 将歌曲作为 mp3 从 ipod 音乐库导入应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28870683/

相关文章:

ios - 从任务管理器关闭应用程序时强制触摸应用程序图标

iphone - 核心音频(Audio Units) Audio Session 和 MPVolumeView

iphone - Apple TestFlight(测试版)应用程序无法安装

ios - 在 Webview 的末尾,显示一条下划线。如何去除 IOS 8 beta 中的下划线?

ios - iOS 6 是否支持 OpenSSL?

jquery - 移动 GPU 加速 slideToggle 功能

iphone - 如何在 iOS 版 Google Places API 中查找当前用户位置

ios - 如何在干净的淡入淡出动画中将 ImageView 的图像更改为另一个图像? (不仅仅是简单的 alpha 更改。)

iOS:如何区分iPhone模式和iPad模式?

iphone - 获取响应映射对象的Json字符串 restkit v0.2.20