仅在函数完成创建视频时才从视频中检索UIImage-swift-以编程方式快速

问题描述

我正在使用UIImages通过视频创建generateCGImagesAsynchronouslyForTimes

fileprivate func createImageFramesFromVideo(completion: @escaping ([UIImage]) -> Void) {
    guard let url = self.videoUrl else {
        return
    }
    
    let asset = AVAsset(url: url)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    let videoDuration = asset.duration
    
    //getting image snapshots more or less in half the video
    let time1 = CMTime(value: videoDuration.value/2 - videoDuration.value/10,timescale: videoDuration.timescale)
    let time2 = CMTime(value: videoDuration.value/2 - videoDuration.value/11,timescale: videoDuration.timescale)
    let time3 = CMTime(value: videoDuration.value/2 - videoDuration.value/12,timescale: videoDuration.timescale)
    let time4 = CMTime(value: videoDuration.value/2,timescale: videoDuration.timescale)
    let time5 = CMTime(value: videoDuration.value/2 + videoDuration.value/12,timescale: videoDuration.timescale)
    let time6 = CMTime(value: videoDuration.value/2 + videoDuration.value/11,timescale: videoDuration.timescale)
    let time7 = CMTime(value: videoDuration.value/2 + videoDuration.value/10,timescale: videoDuration.timescale)
    
    var imageArray : [UIImage] = []
    
    imageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue(time: time1),NSValue(time: time2),NSValue(time: time3),NSValue(time: time4),NSValue(time: time5),NSValue(time: time6),NSValue(time: time7)]) { (time,image,time1,result,err) in
        if let err = err {
            print("there's an error in retrieving the images",err)
        }
       
        let theImage = UIImage(cgImage: image!)
        
        imageArray.append(theImage)
        
        if(result == .succeeded){
            completion(imageArray)
        }
    }
}

由于该函数的完成处理程序被称为每次,因此创建了新图像,因此completion()被多次调用。

我想实现仅在创建所有图像(在本例中为7个)之后调用completion()。 我该怎么办?

解决方法

您需要使用DispatchGroup等待多个异步功能完成。您需要确保对DispatchGroup.enter()leave()的调用是均衡的(调用相同的次数),因为当您使用dispatchGroup.notify(queue:)时,闭包将只执行一次{{1 }}已被每个leave()调用。

您需要为enter()数组的每个元素调用enter(它将包含times变量CMTimetime1,然后在完成时time7的块中调用generateCGImagesAsynchronously(forTimes:,这确保leave()仅在notify(queue:)调用所有图像自己的完成功能后才执行其关闭操作。

generateCGImagesAsynchronously

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...