如何从iPhone/iPod的音乐库中拷贝音乐到自己的App里

最近做的app需要从iOS系统的音乐库里面拷贝选中的歌曲到APP的Documents目录下,在网上找了好久之后,终于找到两种方法,分别是可以导出成指定的格式和导出成Core Audio支持的caf格式,代码分别记录在下面

       1,导出成caf格式,这种导出方式,文件名必须以.caf作为后缀,使用其他后缀会导出失败

  1. - (void) convertToCAF:(NSString *)filename (MPMediaItem *)song  
  2. {  
  3.     NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];  
  4.     AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];  
  5.       
  6.     NSError *assetError = nil;  
  7.     AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset  
  8.                                                                 error:&assetError]  
  9.                                   retain];  
  10.     if (assetError) {  
  11.         NSLog (@"error: %@", assetError);  
  12.         return;  
  13.     }  
  14.       
  15.     AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput  
  16.                                                assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks  
  17.                                                audioSettings: nil]  
  18.                                               retain];  
  19.     if (! [assetReader canAddOutput: assetReaderOutput]) {  
  20.         NSLog (@"can't add reader output... die!");  
  21.         return;  
  22.     }  
  23.     [assetReader addOutput: assetReaderOutput];  
  24.       
  25.     NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  26.     NSString *documentsDirectoryPath = [dirs objectAtIndex:0];  
  27.     NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:filename] retain];  
  28.     if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {  
  29.         [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];  
  30.     }  
  31.     NSURL *exportURL = [NSURL fileURLWithPath:exportPath];  
  32.     AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL  
  33.                                                           fileType:AVFileTypeCoreAudioFormat  
  34.                                                               error:&assetError]  
  35.                                   retain];  
  36.     if (assetError) {  
  37.         NSLog (@"error: %@", assetError);  
  38.         return;  
  39.     }  
  40.     AudioChannelLayout channelLayout;  
  41.     memset(&channelLayout, 0, sizeof(AudioChannelLayout));  
  42.     channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;  
  43.     NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:  
  44.                                     [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,  
  45.                                     [NSNumber numberWithFloat:44100.0], AVSampleRateKey,  
  46.                                     [NSNumber numberWithInt:2], AVNumberOfChannelsKey,  
  47.                                     [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,  
  48.                                     [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,  
  49.                                     [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,  
  50.                                     [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,  
  51.                                     [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,  
  52.                                     nil];  
  53.     AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio  
  54.                                                                                outputSettings:outputSettings]  
  55.                                             retain];  
  56.     if ([assetWriter canAddInput:assetWriterInput]) {  
  57.         [assetWriter addInput:assetWriterInput];  
  58.     } else {  
  59.         NSLog (@"can't add asset writer input... die!");  
  60.         return;  
  61.     }  
  62.       
  63.     assetWriterInput.expectsMediaDataInRealTime = NO;  
  64.       
  65.     [assetWriter startWriting];  
  66.     [assetReader startReading];  
  67.       
  68.     AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];  
  69.     CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);  
  70.     [assetWriter startSessionAtSourceTime: startTime];  
  71.       
  72.     __block UInt64 convertedByteCount = 0;  
  73.       
  74.     dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);  
  75.     [assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue  
  76.                                             usingBlock: ^  
  77.      {  
  78.          // NSLog (@"top of block");  
  79.          while (assetWriterInput.readyForMoreMediaData) {  
  80.              CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];  
  81.              if (nextBuffer) {  
  82.                  // append buffer  
  83.                  [assetWriterInput appendSampleBuffer: nextBuffer];  
  84.                  //             NSLog (@"appended a buffer (%d bytes)",  
  85.                  //                    CMSampleBufferGetTotalSampleSize (nextBuffer));  
  86.                  convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);  
  87.         
  88.                    
  89.              } else {  
  90.                  // done!  
  91.                  [assetWriterInput markAsFinished];  
  92.                  [assetWriter finishWriting];  
  93.                  [assetReader cancelReading];  
  94.                  NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]  
  95.                                                        attributesOfItemAtPath:exportPath  
  96.                                                        error:nil];  
  97.                  NSLog (@"done. file size is %lld",  
  98.                         [outputFileAttributes fileSize]);  
  99.                    
  100.                  // release a lot of stuff  
  101.                  [assetReader release];  
  102.                  [assetReaderOutput release];  
  103.                  [assetWriter release];  
  104.                  [assetWriterInput release];  
  105.                  [exportPath release];  
  106.                  break;  
  107.              }  
  108.          }  
  109.            
  110.      }];  

上面的代码来自  http://www.subfurther.com/blog/2010/12/13/from-ipod-library-to-pcm-samples-in-far-fewer-steps-than-were-previously-necessary/ ,删减了一些更新界面的代码。

2,导出成mp3或者其他格式

  1. - (void) convertToMp3: (MPMediaItem *)song  
  2. {  
  3.     NSURL *url = [song valueForProperty:MPMediaItemPropertyAssetURL];  
  4.       
  5.     AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil];  
  6.       
  7.     NSFileManager *fileManager = [NSFileManager defaultManager];  
  8.     NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  9.     NSString *documentsDirectoryPath = [dirs objectAtIndex:0];  
  10.       
  11.     NSLog (@"compatible presets for songAsset: %@",[AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]);  
  12.       
  13.     NSArray *ar = [AVAssetExportSession exportPresetsCompatibleWithAsset: songAsset];  
  14.     NSLog(@"%@", ar);  
  15.       
  16.     AVAssetExportSession *exporter = [[AVAssetExportSession alloc]  
  17.                                       initWithAsset: songAsset  
  18.                                       presetName: AVAssetExportPresetAppleM4A];  
  19.       
  20.     NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);  
  21.       
  22.     exporter.outputFileType = @"com.apple.m4a-audio";  
  23.       
  24.     NSString *exportFile = [documentsDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.m4a",[song valueForProperty:MPMediaItemPropertyTitle]]];  
  25.       
  26.     NSError *error1;  
  27.       
  28.     if([fileManager fileExistsAtPath:exportFile])  
  29.     {  
  30.         [fileManager removeItemAtPath:exportFile error:&error1];  
  31.     }  
  32.       
  33.     NSURL* exportURL = [[NSURL fileURLWithPath:exportFile] retain];  
  34.       
  35.     exporter.outputURL = exportURL;  
  36.       
  37.     // do the export  
  38.     [exporter exportAsynchronouslyWithCompletionHandler:^  
  39.      {  
  40.          NSData *data1 = [NSData dataWithContentsOfFile:exportFile];  
  41.          //NSLog(@"==================data1:%@",data1);  
  42.            
  43.            
  44.          int exportStatus = exporter.status;  
  45.            
  46.          switch (exportStatus) {  
  47.                    
  48.              case AVAssetExportSessionStatusFailed: {  
  49.                    
  50.                  // log error to text view  
  51.                  NSError *exportError = exporter.error;  
  52.                    
  53.                  NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);  
  54.                    
  55.                    
  56.                    
  57.                  break;  
  58.              }  
  59.                    
  60.              case AVAssetExportSessionStatusCompleted: {  
  61.                    
  62.                  NSLog (@"AVAssetExportSessionStatusCompleted");  
  63.                    
  64.                    
  65.                  break;  
  66.              }  
  67.                    
  68.              case AVAssetExportSessionStatusUnknown: {  
  69.                  NSLog (@"AVAssetExportSessionStatusUnknown");  
  70.                  break;  
  71.              }  
  72.              case AVAssetExportSessionStatusExporting: {  
  73.                  NSLog (@"AVAssetExportSessionStatusExporting");  
  74.                  break;  
  75.              }  
  76.                    
  77.              case AVAssetExportSessionStatusCancelled: {  
  78.                  NSLog (@"AVAssetExportSessionStatusCancelled");  
  79.                  break;  
  80.              }  
  81.                    
  82.              case AVAssetExportSessionStatusWaiting: {  
  83.                  NSLog (@"AVAssetExportSessionStatusWaiting");  
  84.                  break;  
  85.              }  
  86.                    
  87.              default:   
  88.              { NSLog (@"didn't get export status");   
  89.                  break;  
  90.              }  
  91.          }  
  92.            
  93.      }];  

以上的代码参考了 http://stackoverflow.com/questions/4746349/copy-ipod-music-library-audio-file-to-iphone-app-folder 这个帖子, 他原帖中创建AVAssetExportSession时用的是这样的创建方式

  1. AVAssetExportSession *exporter = [[AVAssetExportSession alloc]  
  2.                                       initWithAsset: songAsset  
  3.                                       presetName: AVAssetExportPresetPassthrough];


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值