Сохранить песню в папку с документами из музыкальной библиотеки ios
Я создаю музыкальное приложение, в котором пользователь может получить доступ к музыкальной библиотеке ios и сохранить песни в своем приложении (это каталог документов). Я могу получить доступ к музыкальной библиотеке с помощью MPMediaPickerController, но не знаю, как обработать его метод делегата, чтобы сохранить выбранную песню в папку с документами. В настоящее время я использую этот код
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker
didPickMediaItems: (MPMediaItemCollection *) collection
{
[self dismissViewControllerAnimated:YES completion:nil];
[self playSelectedMediaCollection: collection];
}
- (void) playSelectedMediaCollection: (MPMediaItemCollection *) collection {
if (collection.count == 1) {
NSArray *items = collection.items;
MPMediaItem *mediaItem = [items objectAtIndex:0];
[self mediaItemToData:mediaItem];
}
}
-(void)mediaItemToData:(MPMediaItem*)mediaItem
{
// Implement in your project the media item picker
MPMediaItem *curItem = mediaItem;//musicPlayer.nowPlayingItem;
NSURL *url = [curItem valueForProperty: MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset
presetName: AVAssetExportPresetPassthrough];
exporter.outputFileType = @"public.mpeg-4";
NSString *exportFile = [[self myDocumentsDirectory] stringByAppendingPathComponent:
@"exported.mp4"];
NSURL *exportURL = [NSURL fileURLWithPath:exportFile] ;
exporter.outputURL = exportURL;
NSData *data = [NSData dataWithContentsOfFile: [[self myDocumentsDirectory]
stringByAppendingPathComponent: @"exported.mp4"]];
//
// NSLog(@"%@",data);
// NSURL *audioUrl = exportURL;
// NSLog(@"Audio Url=%@",audioUrl);
// audioData = [NSData dataWithContentsOfURL:audioUrl];
// NSLog(@"%@",audioData);
// Do with data something
// do the export
// (completion handler block omitted)
[exporter exportAsynchronouslyWithCompletionHandler:
^{
// int exportStatus=exporter.status;
NSLog(@"%d export status",exporter.status);
if (exporter.status==AVAssetExportSessionStatusCompleted)
{
NSLog(@"successfull");
}
NSData *data = [NSData dataWithContentsOfFile: [[self myDocumentsDirectory]
stringByAppendingPathComponent: @"exported.mp4"]];
NSURL *audioUrl = exportURL;
NSLog(@"Audio Url=%@",audioUrl);
audioData = [NSData dataWithContentsOfURL:audioUrl];
NSLog(@"%@",audioData);
// Do with data something
}];
}
В приведенном выше коде отладчик никогда не приходит в асинхронный блок сеанса экспорта. Сообщите мне, есть ли какие-либо изменения, требуемые в приведенном выше коде, или если у вас есть какой-либо рабочий код, доступный для моего требования. Заранее спасибо....
2 ответа
Я думаю, что было пропущено
/
попробуй этот код
NSString *exportFile = [[self myDocumentsDirectory] stringByAppendingPathComponent: @"/exported.mp4"];
ОБНОВЛЕНО
или причина может быть presetName, который вы используете
/ * Эта опция экспорта приведет к тому, что медиа всех дорожек будут передаваться на выход точно так, как они хранятся в исходном ресурсе, за исключением дорожек, для которых проход невозможен, как правило, из-за ограничений формата контейнера, как указано указанным outputFileType. Эта опция не включена в массивы, возвращаемые -allExportPresets и -exportPresetsCompatibleWithAsset. */ AVF_EXPORT NSString *const AVAssetExportPresetPassthrough NS_AVAILABLE(10_7, 4_0);
Вот хорошее описание ExportAsynchronouslyWithCompletionHandler: https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AVAssetExportSession_Class/Reference/Reference.html
Для Swift 3.0 или 4
func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
mediaPicker.dismiss(animated: true) {
print("You selected \(mediaItemCollection)")
let item: MPMediaItem = mediaItemCollection.items[0]
let pathURL: URL? = item.value(forProperty: MPMediaItemPropertyAssetURL) as? URL
if pathURL == nil {
print("Picking Error")
return
}
// get file extension andmime type
let str = pathURL!.absoluteString
let str2 = str.replacingOccurrences( of : "ipod-library://item/item", with: "")
let arr = str2.components(separatedBy: "?")
var mimeType = arr[0]
mimeType = mimeType.replacingOccurrences( of : ".", with: "")
// Export the ipod library as .m4a file to local directory for remote upload
let exportSession = AVAssetExportSession(asset: AVAsset(url: pathURL!), presetName: AVAssetExportPresetAppleM4A)
exportSession?.shouldOptimizeForNetworkUse = true
exportSession?.outputFileType = AVFileTypeAppleM4A
let documentURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let outputURL = documentURL.appendingPathComponent("custom.m4a")
//Delete Existing file
do {
try FileManager.default.removeItem(at: outputURL)
} catch let error as NSError {
print(error.debugDescription)
}
exportSession?.outputURL = outputURL
exportSession?.exportAsynchronously(completionHandler: { () -> Void in
if exportSession!.status == AVAssetExportSessionStatus.completed {
print("Export Successfull")
}
})
}
}