【问题标题】:Save song to document directory from ios music library将歌曲从 ios 音乐库保存到文档目录
【发布时间】: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

     }];
}

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

【问题讨论】:

    标签: ios iphone objective-c mpmusicplayercontroller avassetexportsession


    【解决方案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 或其他。
    猜你喜欢
    • 2014-04-19
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多