Сохранить песню в каталог документов из музыкальной библиотеки 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

     }];
}

В приведенном выше коде отладчик никогда не переходит к асинхронному блоку сеанса экспорта. Сообщите мне, требуются ли какие-либо изменения в приведенном выше коде или у вас есть рабочий код, доступный для моих требований. Заранее спасибо....


person Rahul Mathur    schedule 27.02.2014    source источник


Ответы (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

person andproff    schedule 27.02.2014
comment
По-прежнему не удается отладить блок [экспортер exportAsynchronouslyWithCompletionHandler: Я просто хочу во-первых, почему мой запрос компилятора переходит в этот блок и почему я не могу получить свой статус экспорта - person Rahul Mathur; 27.02.2014
comment
Блок вызывается, но каждый раз мой статус экспорта равен 4, т.е. сбой. Я не знаю, что мне не хватает. - person Rahul Mathur; 28.02.2014
comment
вы спрашиваете о рабочем коде с сеансом экспорта… пробовали ли вы этот пример? - person andproff; 28.02.2014
comment
поддерживает ли сеанс экспорта файлы mp3? - person Rahul Mathur; 01.03.2014
comment
@RahulMathur, да, он поддерживает этот документ developer.apple.com/library/mac/documentation/AVFoundation/ - person Tirth; 07.03.2014

для 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")
            }

        })

    }

}
person Return Zero    schedule 07.02.2018
comment
Привет! Может быть, вы знаете, как экспортировать файлы в формат, как они есть в Музыкальной библиотеке? Без конвертации в m4a или другое. - person VyacheslavBakinkskiy; 24.11.2020