首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVAssetExportSession进度不更新

AVAssetExportSession进度不更新
EN

Stack Overflow用户
提问于 2019-08-05 03:27:53
回答 1查看 264关注 0票数 0

我使用AVAssetExportSession将电影导出为MP4格式,使用以下代码:

步骤1:用户单击按钮开始转换

代码语言:javascript
复制
@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:触发器转换视频函数

代码语言:javascript
复制
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()中添加如下:

代码语言:javascript
复制
NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveConvertProgress(_:)), name: Notification.Name(Constants.Notifications.ConvertProgress.rawValue), object: nil)

状态更新功能(两次尝试)如下:

代码语言:javascript
复制
@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
}

我错过了什么?

EN

回答 1

Stack Overflow用户

发布于 2020-03-05 18:43:12

我不确定您是否理解了这一点,但是为了防止其他人尝试您的代码,进度定时器没有启动的问题是因为您遗漏了两件事情。

  1. 您从未调用该函数来启动计时器。例如self.exportTimer.fire()
  2. 您必须确保更新主队列上的这个计时器。

我有同样的问题,做这两件事解决了我的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57351860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档