AVAssetExportSession.requestExportSessioncallback从未调用(swift 3,iOS10)

下面的代码永远不会调用导出的callback。 导出会话创build得很好。 我没有看到任何错误,也没有任何进展。 CPU是0%。 我看没有例外。 状态为1(进行中),进度为0,错误为零。 video在画廊中播放。 我可以成功获取video的图像。 我已经提取代码到单个UIViewController进行testing,请参阅下面:

我使用iOS10.1.1testing了iPad上录制的video。

import UIKit import Photos class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: Properties @IBOutlet weak var button: UIButton! // MARK: Actions @IBAction func onPress(_ sender: UIButton) { requestGalleryPermission() { (_ hasPermission: Bool) in if hasPermission { // fetch the asset from Photos let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: ["9FFAD8B5-0941-4A95-830F-4ACFA563B71B/L0/001"], options: nil) // if we successfully fetched the asset... if let asset = fetchResult.firstObject { self.exportAsset(asset) } } } } func exportAsset(_ asset: PHAsset) { let tempFilename = "full_sized_image.mov" var tempURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(tempFilename) tempURL = tempURL.standardizedFileURL let options = PHVideoRequestOptions() options.deliveryMode = .highQualityFormat options.isNetworkAccessAllowed = true // remove any existing file at that location do { try FileManager.default.removeItem(at: tempURL) } catch { // most likely, the file didn't exist. Don't sweat it } PHImageManager.default().requestExportSession(forVideo: asset, options: options, exportPreset: AVAssetExportPresetHighestQuality) { (exportSession: AVAssetExportSession?, _) in if exportSession == nil { print("COULD NOT CREATE EXPORT SESSION") return } exportSession!.outputURL = tempURL exportSession!.outputFileType = AVFileTypeQuickTimeMovie print("GOT EXPORT SESSION") exportSession!.exportAsynchronously() { print("COMPLETION HANDLER!!!!") } print("progress: \(exportSession!.progress)") print("error: \(exportSession!.error)") print("status: \(exportSession!.status.rawValue)") } } func requestGalleryPermission(_ completionHandler: @escaping (_ hasPermission: Bool) -> Void) { let authorizationStatus = PHPhotoLibrary.authorizationStatus() if authorizationStatus == .denied || authorizationStatus == .restricted { completionHandler(false) } else if authorizationStatus == .authorized { completionHandler(true) } else { // ask for authorization PHPhotoLibrary.requestAuthorization({ (status: PHAuthorizationStatus) in // if the user gave us authorization... if status == .authorized { print("User gave authorization") completionHandler(true) } else { print("User denied authorization") completionHandler(false) } }) } } } 

Swift 3对我来说就像一个魅力!

 func exportVideoAsset(_ asset: PHAsset) { let filename = UUID().uuidString.appending(".mp4") // setting random file name let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! do { var fileurl = try documentsUrl.absoluteString.appending(filename).asURL() print("exporting video to ", fileurl) fileurl = fileurl.standardizedFileURL let options = PHVideoRequestOptions() options.deliveryMode = .highQualityFormat options.isNetworkAccessAllowed = true // remove any existing file at that location do { try FileManager.default.removeItem(at: fileurl) } catch { // most likely, the file didn't exist. Don't sweat it } PHImageManager.default().requestExportSession(forVideo: asset, options: options, exportPreset: AVAssetExportPresetHighestQuality) { (exportSession: AVAssetExportSession?, _) in if exportSession == nil { print("COULD NOT CREATE EXPORT SESSION") return } exportSession!.outputURL = fileurl exportSession!.outputFileType = AVFileTypeMPEG4 //file type encode goes here, you can change it for other types print("GOT EXPORT SESSION") exportSession!.exportAsynchronously() { print("EXPORT DONE") } print("progress: \(exportSession!.progress)") print("error: \(exportSession!.error)") print("status: \(exportSession!.status.rawValue)") } } catch { // something may happend here, like no disk space } }