在我的应用程序中,我想从音乐库导出文件并将其保存到Documents目录。我已经从音乐库中获取了文件列表,并获得了每个文件的url。但我仍然有两个问题:
-
我只能在";m4a";格式,但我想以音乐库中的文件格式导出(mp3、wav、aac或其他(
-
如何使用url将音乐库中的文件保存到Documents目录?我的代码现在看起来是这样的:
private func exportFile(with assetURL: URL, completionHandler: @escaping (_ fileURL: URL?, _ error: Error?) -> ()) { let asset = AVURLAsset(url: assetURL) guard let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else { completionHandler(nil, nil) return } let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()) .appendingPathComponent(NSUUID().uuidString) .appendingPathExtension("m4a") exporter.outputURL = fileURL exporter.outputFileType = AVFileType.m4a exporter.exportAsynchronously { if exporter.status == .completed { completionHandler(fileURL, nil) } else { completionHandler(nil, exporter.error) } } func downloadFile(file: MPMediaItem?, callback: @escaping () -> ()) { guard let file = file, let url = file.url else { return } exportFile(with: url) { fileURL, error in guard let fileURL = fileURL, error == nil else { print(error?.localizedDescription) return } //Here I'd like to save file to Documents dir print("(fileURL)") } callback() }
第二个问题的解决方案
我把代码放在一种方法中,并直接保存到Documents文件夹,而不是临时文件夹:
func downloadFile(file: MPMediaItem?, callback: @escaping () -> ()) {
guard let file = file,
let url = file.assetURL
else { return }
let exportSession = AVAssetExportSession(asset: AVAsset(url: url), presetName: AVAssetExportPresetAppleM4A)
exportSession?.shouldOptimizeForNetworkUse = true
exportSession?.outputFileType = AVFileType.m4a
let documentURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let outputURL = documentURL.appendingPathComponent("(file.title!).m4a")
// //Delete Existing file if needs
// do {
// try FileManager.default.removeItem(at: outputURL)
// } catch let error as NSError {
// print(error.debugDescription)
// }
exportSession?.outputURL = outputURL
exportSession?.exportAsynchronously(completionHandler: { () -> () in
if exportSession!.status == AVAssetExportSession.Status.completed {
print("Export Successful")
DispatchQueue.main.async {
//Update IU
callback()
}
} else {
print("Export failed")
}
})
}