将歌曲从 ios 音乐库保存到文档目录

Posted

技术标签:

【中文标题】将歌曲从 ios 音乐库保存到文档目录【英文标题】:Save song to document directory from ios music library 【发布时间】:2014-02-27 06:35:18 【问题描述】:

我正在制作一个音乐应用程序,用户可以在其中访问 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

     ];

在上面的代码中,调试器永远不会来到导出会话异步块。让我知道上述代码中是否需要任何修改,或者您是否有任何工作代码可满足我的要求。 提前谢谢....

【问题讨论】:

【参考方案1】:

我认为是错过了

/

试试这个代码

NSString *exportFile = [[self myDocumentsDirectory] stringByAppendingPathComponent: @"/exported.mp4"];

更新

或者原因可以是您使用的预设名称

/* 此导出选项将导致所有轨道的媒体完全按照存储在源资产中的方式传递到输出,除了 无法通过的轨道,通常是因为指定的 outputFileType 指示的容器格式的限制。 此选项不包含在 -allExportPresets 和 -exportPresetsCompatibleWithAsset 返回的数组中。 */ AVF_EXPORT NSString *const AVAssetExportPresetPassthrough NS_AVAILABLE(10_7, 4_0);

这里是关于 exportAsynchronouslyWithCompletionHandler 的很好的描述:https://developer.apple.com/library/mac/documentation/AVFoundation/Reference/AV‌​AssetExportSession_Class/Reference/Reference.html

【讨论】:

仍然无法调试块 [exporter exportAsynchronouslyWithCompletionHandler: 我只想知道首先,为什么我的编译器会进入这个块以及为什么我无法获得我的导出状态 正在调用该块,但每次我的导出状态为 4 即失败。我不知道我错过了什么。 您询问有关导出会话的工作代码...您尝试过this example吗? 导出会话是否支持 mp3 文件? @RahulMathur 是的,它支持通过这个文档developer.apple.com/library/mac/documentation/AVFoundation/…【参考方案2】:

对于 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")
            

        )

    


【讨论】:

嗨!也许您知道如何将文件导出为音乐库中的格式?无需转换为 m4a 或其他。

以上是关于将歌曲从 ios 音乐库保存到文档目录的主要内容,如果未能解决你的问题,请参考以下文章

QQ音乐在线听那歌会保存在哪个文档?

ios 7.1 将歌曲添加到音乐库

将相机捕获的图像保存到ios中的文档目录中[重复]

如何将数组保存到ios文档目录?

iOS AVAudioPlayer OSStatus 错误 -43

我可以在 iOS 中使用 iPodMusicPlayer 播放文档目录中的歌曲吗?