简体   繁体   English

是否可以使用swift将Ipod库中的音乐保存到我的应用程序中?

[英]Is it possible to save a music from the Ipod library into my app with swift?

I have the reference of an MPMediaItem when a user selects an audio from the iPod library. 当用户从iPod库中选择音频时,我会引用MPMediaItem。 I am getting the asset URL of that item by using 我通过使用获取该项目的资产URL

 let url = item.valueForProperty(MPMediaItemPropertyAssetURL)

But this is not giving me the exact physical location of the file, instead, it is giving me an URL wrt iPod library. 但这并没有给我文件的确切物理位置,相反,它给了我一个URL与iPod库。

ipod-library://item/item.mp3?id=1840064795502796074

Is there a way to get the physical URL of a song from an iPod library? 有没有办法从iPod库中获取歌曲的物理URL?

EDIT - actually I want to extract NSData from the physical file and send it to my backend server, so I need the physical file URL and not the relative URL 编辑 - 实际上我想从物理文件中提取NSData并将其发送到我的后端服务器,所以我需要物理文件URL而不是相对URL

MPmediaPickerController is working, I select the song and its playing but I don't want to play the song.I have tried to upload the audio files to a server. MPmediaPickerController正在工作,我选择了歌曲及其播放,但我不想播放这首歌。我试图将音频文件上传到服务器。 And I have using MPMedia Picker view in list audio, when I am going select the audio I will upload to server(HTTP), How can I do this??? 我在列表音频中使用MPMedia Picker视图,当我要选择我将上传到服务器(HTTP)的音频时,我该怎么做? How to accessing the media library with Swift code? 如何使用Swift代码访问媒体库?

Adapting Krishna's answer, which uses AVAssetExportSession to save the MPMediaItem to a file, you can do something like the following in Swift 3: 适应Krishna的答案,它使用AVAssetExportSession到保存MPMediaItem到一个文件,你可以这样做的雨燕3如下:

/// Export MPMediaItem to temporary file.
///
/// - Parameters:
///   - assetURL: The `assetURL` of the `MPMediaItem`.
///   - completionHandler: Closure to be called when the export is done. The parameters are a boolean `success`, the `URL` of the temporary file, and an optional `Error` if there was any problem. The parameters of the closure are:
///
///   - fileURL: The `URL` of the temporary file created for the exported results.
///   - error: The `Error`, if any, of the asynchronous export process.

func export(_ assetURL: URL, completionHandler: @escaping (_ fileURL: URL?, _ error: Error?) -> ()) {
    let asset = AVURLAsset(url: assetURL)
    guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
        completionHandler(nil, ExportError.unableToCreateExporter)
        return
    }

    let fileURL = URL(fileURLWithPath: NSTemporaryDirectory())
        .appendingPathComponent(NSUUID().uuidString)
        .appendingPathExtension("m4a")

    exporter.outputURL = fileURL
    exporter.outputFileType = "com.apple.m4a-audio"

    exporter.exportAsynchronously {
        if exporter.status == .completed {
            completionHandler(fileURL, nil)
        } else {
            completionHandler(nil, exporter.error)
        }
    }
}

func exampleUsage(with mediaItem: MPMediaItem) {
    if let assetURL = mediaItem.assetURL {
        export(assetURL) { fileURL, error in
            guard let fileURL = fileURL, error == nil else {
                print("export failed: \(error)")
                return
            }

            // use fileURL of temporary file here
            print("\(fileURL)")
        }
    }
}

enum ExportError: Error {
    case unableToCreateExporter
}

Or, in Swift 2: 或者,在Swift 2中:

/// Export MPMediaItem to temporary file.
///
/// - Parameters:
///   - assetURL: The `assetURL` of the `MPMediaItem`.
///   - completionHandler: Closure to be called when the export is done. The parameters are a boolean `success`, the `URL` of the temporary file, and an optional `Error` if there was any problem. The parameters of the closure are:
///
///   - fileURL: The `URL` of the temporary file created for the exported results.
///   - error: The `Error`, if any, of the asynchronous export process.

func export(assetURL: NSURL, completionHandler: (NSURL?, ErrorType?) -> ()) {
    let asset = AVURLAsset(URL: assetURL)
    guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {
        completionHandler(nil, ExportError.unableToCreateExporter)
        return
    }

    let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
        .URLByAppendingPathComponent(NSUUID().UUIDString)!
        .URLByAppendingPathExtension("m4a")

    exporter.outputURL = fileURL
    exporter.outputFileType = "com.apple.m4a-audio"

    exporter.exportAsynchronouslyWithCompletionHandler {
        if exporter.status == .Completed {
            completionHandler(fileURL, nil)
        } else {
            completionHandler(nil, exporter.error)
        }
    }
}

func exampleUsage(with mediaItem: MPMediaItem) {
    if let assetURL = mediaItem.assetURL {
        export(assetURL) { fileURL, error in
            guard let fileURL = fileURL where error == nil else {
                print("export failed: \(error)")
                return
            }

            // use fileURL of temporary file here
            print("\(fileURL)")
        }
    }
}

enum ExportError: ErrorType {
    case unableToCreateExporter
}

As you can see, I put it in a temporary folder rather than the Documents folder. 如您所见,我将其放在临时文件夹而不是Documents文件夹中。 Also, I use UUID rather than the number of seconds since some reference date to generate the temporary file. 此外,我使用UUID而不是自某个引用日期以来生成临时文件的秒数。 But the idea is basically the same. 但这个想法基本相同。

After selecting the song from library convert your MPMediaItem object into NSData and upload it to server using multipart form data. 从库中选择歌曲后,将MPMediaItem对象转换为NSData并使用多部分表单数据将其上载到服务器。

Convert MPMediaItem to NSData 将MPMediaItem转换为NSData

-( void)mediaItemToData : (MPMediaItem * ) curItem
{
    NSURL *url = [curItem valueForProperty: MPMediaItemPropertyAssetURL];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil];

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset
                                                                      presetName:AVAssetExportPresetAppleM4A];

    exporter.outputFileType =   @"com.apple.m4a-audio";

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * myDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;

    [[NSDate date] timeIntervalSince1970];
    NSTimeInterval seconds = [[NSDate date] timeIntervalSince1970];
    NSString *intervalSeconds = [NSString stringWithFormat:@"%0.0f",seconds];

    NSString * fileName = [NSString stringWithFormat:@"%@.m4a",intervalSeconds];

    NSString *exportFile = [myDocumentsDirectory stringByAppendingPathComponent:fileName];

    NSURL *exportURL = [NSURL fileURLWithPath:exportFile];
    exporter.outputURL = exportURL;

    // do the export
    // (completion handler block omitted)
    [exporter exportAsynchronouslyWithCompletionHandler:
     ^{
         int exportStatus = exporter.status;

         switch (exportStatus)
         {
             case AVAssetExportSessionStatusFailed:
             {
                 NSError *exportError = exporter.error;
                 NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);
                 break;
             }
             case AVAssetExportSessionStatusCompleted:
             {
                 NSLog (@"AVAssetExportSessionStatusCompleted");

                 NSData *data = [NSData dataWithContentsOfFile: [myDocumentsDirectory
                                                                 stringByAppendingPathComponent:fileName]];

                 [arrayMusic addObject:data];
                 data = nil;

                 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;
             }
         }
     }];

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM