最近做的app需要从iOS系统的音乐库里面拷贝选中的歌曲到APP的Documents目录下,在网上找了好久之后,终于找到两种方法,分别是可以导出成指定的格式和导出成Core Audio支持的caf格式,代码分别记录在下面
1,导出成caf格式,这种导出方式,文件名必须以.caf作为后缀,使用其他后缀会导出失败
- (void) convertToCAF:(NSString *)filename (MPMediaItem *)song
{
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
NSError *assetError = nil;
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
error:&assetError]
retain];
if (assetError) {
NSLog (@"error: %@", assetError);
return;
}
AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput
assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil]
retain];
if (! [assetReader canAddOutput: assetReaderOutput]) {
NSLog (@"can't add reader output... die!");
return;
}
[assetReader addOutput: assetReaderOutput];
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:filename] retain];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
NSURL *exportURL = [NSURL fileURLWithPath:exportPath];
AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL
fileType:AVFileTypeCoreAudioFormat
error:&assetError]
retain];
if (assetError) {
NSLog (@"error: %@", assetError);
return;
}
AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
[NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
nil];
AVAssetWriterInput *assetWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings]
retain];
if ([assetWriter canAddInput:assetWriterInput]) {
[assetWriter addInput:assetWriterInput];
} else {
NSLog (@"can't add asset writer input... die!");
return;
}
assetWriterInput.expectsMediaDataInRealTime = NO;
[assetWriter startWriting];
[assetReader startReading];
AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
[assetWriter startSessionAtSourceTime: startTime];
__block UInt64 convertedByteCount = 0;
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock: ^
{
// NSLog (@"top of block");
while (assetWriterInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
// append buffer
[assetWriterInput appendSampleBuffer: nextBuffer];
// NSLog (@"appended a buffer (%d bytes)",
// CMSampleBufferGetTotalSampleSize (nextBuffer));
convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
} else {
// done!
[assetWriterInput markAsFinished];
[assetWriter finishWriting];
[assetReader cancelReading];
NSDictionary *outputFileAttributes = [[NSFileManager defaultManager]
attributesOfItemAtPath:exportPath
error:nil];
NSLog (@"done. file size is %lld",
[outputFileAttributes fileSize]);
// release a lot of stuff
[assetReader release];
[assetReaderOutput release];
[assetWriter release];
[assetWriterInput release];
[exportPath release];
break;
}
}
}];
}
上面的代码来自 http://www.subfurther.com/blog/2010/12/13/from-ipod-library-to-pcm-samples-in-far-fewer-steps-than-were-previously-necessary/ ,删减了一些更新界面的代码。
2,导出成mp3或者其他格式
- (void) convertToMp3: (MPMediaItem *)song
{
NSURL *url = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
NSLog (@"compatible presets for songAsset: %@",[AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]);
NSArray *ar = [AVAssetExportSession exportPresetsCompatibleWithAsset: songAsset];
NSLog(@"%@", ar);
AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
initWithAsset: songAsset
presetName: AVAssetExportPresetAppleM4A];
NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);
exporter.outputFileType = @"com.apple.m4a-audio";
NSString *exportFile = [documentsDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.m4a",[song valueForProperty:MPMediaItemPropertyTitle]]];
NSError *error1;
if([fileManager fileExistsAtPath:exportFile])
{
[fileManager removeItemAtPath:exportFile error:&error1];
}
NSURL* exportURL = [[NSURL fileURLWithPath:exportFile] retain];
exporter.outputURL = exportURL;
// do the export
[exporter exportAsynchronouslyWithCompletionHandler:^
{
NSData *data1 = [NSData dataWithContentsOfFile:exportFile];
//NSLog(@"==================data1:%@",data1);
int exportStatus = exporter.status;
switch (exportStatus) {
case AVAssetExportSessionStatusFailed: {
// log error to text view
NSError *exportError = exporter.error;
NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);
break;
}
case AVAssetExportSessionStatusCompleted: {
NSLog (@"AVAssetExportSessionStatusCompleted");
break;
}
case AVAssetExportSessionStatusUnknown: {
NSLog (@"AVAssetExportSessionStatusUnknown");
break;
}
case AVAssetExportSessionStatusExporting: {
NSLog (@"AVAssetExportSessionStatusExporting");
break;
}
case AVAssetExportSessionStatusCancelled: {
NSLog (@"AVAssetExportSessionStatusCancelled");
break;
}
case AVAssetExportSessionStatusWaiting: {
NSLog (@"AVAssetExportSessionStatusWaiting");
break;
}
default:
{ NSLog (@"didn't get export status");
break;
}
}
}];
}
以上的代码参考了 http://stackoverflow.com/questions/4746349/copy-ipod-music-library-audio-file-to-iphone-app-folder 这个帖子, 他原帖中创建AVAssetExportSession时用的是这样的创建方式
AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
initWithAsset: songAsset
presetName: AVAssetExportPresetPassthrough];
但是这样的代码在我的APP上不能工作,所以把最后一个参数改成了AVAssetExportPresetAppleM4A,可以通过 [AVAssetExportSession exportPresetsCompatibleWithAsset:song]来获取歌曲支持哪些preset。
分享到:
相关推荐
仿iPhone/iPod动态图片浏览器 仿iPhone/iPod动态图片浏览器 仿iPhone/iPod动态图片浏览器
iPhone/ipod touch/ipad文件传输工具 ifunBox_sc中文版(数据线版)支持 iFunBox:PC 端程序,简单、高效,只需要 iTunes 环境支持,数据线传输,速度一般 10MB/S i-FunBox v0.99版本, 更新信息: 1. 传输文件到...
实现特殊效果的按钮。按钮的形状类似物理键盘按钮,按钮未点击时是凸起状态,用户点击按钮,按钮会呈现压下去的效果,用户松开按钮,按钮又会凸起。 注意:请在Mac下解压使用
treemapkit, Cocoa Touch for ( iphone/ipod touch/ipad ) TreemapKitTreemapKit是 Cocoa Touch的treemap实现。 你可以在 iPhone,iPod touch和iPad中显示 TreeMaps 。点击这里看一下简单的演示软件。 许可证...
一款专门清理 iPhone/iPad/iPod 垃圾文件的程序,傻瓜式应用,手机连上电脑,一路下一步,清理内容包括:临时文件、缓存、浏览器历史、同步失败错误残留数据等等。
请从https://blog.csdn.net/softlgh/article/details/40507623页面中的最新地址下载。跨平台声波通讯库(新版) 声波通讯库特征: 准确性95%以上,其实一般是不会出错的。 接口非常简单,有完整的示例,3分钟就可以...
iOSList, jQuery iOS (iPhone/iPad/iPod) 按字母顺序联系人列表 iOSList 2.0.6带有jQuery的ios风格的置顶头iOSList是一个可以用于创建ios风格置顶头的jQuery插件,类似于苹果设备上的音乐和联系人应用。 测试可以在...
14.0真机调试包 安装路径:/应用程序/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/De
Axure iphone/ipad资源库,解压后有4个rplib文件,分别是iphone及ipad的UI库
自定义状态栏(Status Bar),支持两种点击动作:1. 当用户点击状态栏时,状态栏会收缩,仅仅遮盖住状态栏右方的电池图标; 2. 当用户点击状态栏时,一个有详细信息的视图会下拉出现。 注意:请在Mac下解压使用
软件可以将音乐、视频、照片、游戏等各种多媒体文件从iPod或iPod中复制到计算机里。,软件还能以目录形式浏览或编辑iPhone/iPod内的文件, 方便的一键备份功能可以轻松备份所有的多媒体文件到itunes或者PC。软件界面...
/应用程序/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
iPhone/iPad 绘图应用 Brushes ,Brushes 是一个绘图应用,支持 iPhone, iPod touch 和 iPad。
即使是AppStore上,都有很多绘画App在迅速画圆圈时,所绘制的圆弧不够平滑,会出现折线(锯齿),这个代码较好地解决了这个问题。代码仅用Quartz解决了这个问题,不需要用到OpenGL。 注意:请在Mac下解压使用
实现treemap效果。接受点击事件。 注意:请在Mac下解压使用
实现的UI是:当用户打开app时,提醒用户给应用打分。 注意:请在Mac下解压使用
自定义进度条的颜色。可以任意改变进度条中移动进度的颜色(UIProgressView默认是蓝色,而且无法改变)。 注意:请在Mac下解压使用
实现能够展示丰富文字效果的label,即在在label上面显示NSAttributedString。,用于代替UILabel,包括给文字加上下划线,链接等等。 注意:请在Mac下解压使用
实现Path应用的按钮效果:点击主按钮,围绕着主按钮四分之一圆弧弹出一些次按钮,点击某个次按钮,所有次按钮都会回收进主按钮。 注意:请在Mac下解压使用