我使用AVAssetExportSession将电影导出为MP4格式,使用以下代码:
步骤1:用户单击按钮开始转换
@IBAction func clickConvert(_ sender:UIButton) {
self.convertProgress?.progress = 0
self.convertProgress?.isHidden = false
var preset = AVAssetExportPresetHighestQuality
switch self.qualitySelection?.selectedSegmentIndex {
case 0:
preset = AVAssetExportPresetLowQuality
break
case 1:
preset = AVAssetExportPresetMediumQuality
break
case 2:
preset = AVAssetExportPresetHighestQuality
break
default:
break
}
DispatchQueue.global(qos: .background).async {
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMddHHmmss"
let fileName = formatter.string(from: Date()) + ".mp4"
let convertGroup = DispatchGroup()
convertGroup.enter()
do {
let documentDirectory = try self.fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
let filePath = documentDirectory.appendingPathComponent(fileName)
if(self.videoURL != nil) {
self.convertVideo(fromURL: self.videoURL!, toURL: filePath, preset: preset, dispatchGroup: convertGroup)
} else {
print("nil Video URL")
}
convertGroup.notify(queue: DispatchQueue.main) {
// reset Convert button state
self.convertButton?.titleLabel?.text = "Convert"
self.convertButton?.isEnabled = true
self.delegate?.updateFileList()
// Take back to old VC, update file list
if let navController = self.navigationController {
navController.popViewController(animated: true)
}
}
} catch {
print(error)
}
}
}步骤2:触发器转换视频函数
func convertVideo(fromURL: URL, toURL: URL, preset:String, dispatchGroup: DispatchGroup) {
let outFileType = AVFileType.mp4
let inAsset = AVAsset(url: fromURL)
let startDate = Date()
AVAssetExportSession.determineCompatibility(ofExportPreset: preset, with: inAsset, outputFileType: outFileType, completionHandler: { (isCompitable) in
if !isCompitable {
return
}
guard let export = AVAssetExportSession(asset: inAsset, presetName: preset) else {
return
}
export.outputFileType = outFileType
export.outputURL = toURL
export.shouldOptimizeForNetworkUse = true
let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
let range = CMTimeRangeMake(start: start, duration: inAsset.duration)
export.timeRange = range
// Timer for progress updates
self.exportTimer = Timer()
if #available(iOS 10.0, *) {
print("start exportTimer")
self.exportTimer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true, block: { _ in
let progress = Float(export.progress)
print("Export Progress: \(progress)")
self.updateProgressDisplay(progress: progress)
if progress < 0.99 {
let dict:[String: Float] = ["progress": progress]
NotificationCenter.default.post(name: Notification.Name(Constants.Notifications.ConvertProgress.rawValue), object: nil, userInfo: dict)
}
})
}
export.exportAsynchronously { () -> Void in
// Handle export results
switch export.status {
case .exporting:
print("Exporting...")
self.updateProgressDisplay(progress: export.progress)
break
case .failed:
print("Error: %@!", export.error!)
break
case .cancelled:
print("export cancelled")
break
case .completed:
let endDate = Date()
let elapsed = endDate.timeIntervalSince(startDate)
print("Elapsed: \(elapsed)")
print("successful")
self.exportTimer?.invalidate() // Stop the timer
self.generateThumbnail(path: toURL)
break
default:
break
}
dispatchGroup.leave()
}
})
}但是,状态更新不起作用,因为计时器exportTimer从不触发(尝试1),而exportSession.exporting情况永远不会触发(尝试2)。
附注:视频可以转换成没有任何问题。
附注:通知在viewDidLoad()中添加如下:
NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveConvertProgress(_:)), name: Notification.Name(Constants.Notifications.ConvertProgress.rawValue), object: nil)状态更新功能(两次尝试)如下:
@objc func onDidReceiveConvertProgress(_ notification:Notification) {
print ("onDidReceiveConvertProgress")
if let data = notification.userInfo as? [String:Float] {
print("Progress: \(String(describing: data["progress"]))")
self.convertProgress?.progress = data["progress"]!
}
}
func updateProgressDisplay(progress: Float) {
print("updateProgressDisplay")
self.convertProgress?.progress = progress
}我错过了什么?
发布于 2020-03-05 18:43:12
我不确定您是否理解了这一点,但是为了防止其他人尝试您的代码,进度定时器没有启动的问题是因为您遗漏了两件事情。
我有同样的问题,做这两件事解决了我的问题。
https://stackoverflow.com/questions/57351860
复制相似问题