我如何知道generateCGImages异步完成的时间?

时间:2016-09-22 13:52:55

标签: ios swift avfoundation avasset avassetimagegenerator

我需要拍摄视频,将每个帧转换为图像并将这些图像保存到磁盘。为了提高效率,我想使用AVAssetImageGenerator,并且代码类似于以下代码:

问题是我不知道所有图像生成何时完成,但是我需要在所有帧都写入磁盘后采取措施。例如:

assetGenerator.generateCGImagesAsynchronously(forTimes: frameTimes, completionHandler: { (requestedTime, image, actualTime, result, error) in
    // 1. Keep a reference to each image
    // 2. Wait until all images are generated
    // 3. Process images as a set
})

这是上面的第二步,这让我感到沮丧。我想我可以尝试计算调用完成处理程序的次数,并在计数等于帧数时触发适当的方法。

但是我想知道是否有办法使用API​​来了解每个帧何时被处理?也许只是我错过的东西?任何指导或建议将不胜感激。

1 个答案:

答案 0 :(得分:6)

我会逐步处理图像,无论如何你都无法将它们全部放入内存中。为此,您可以使用AVAssetReader在特定时间对视频进行采样。

但是你可以过采样(重复帧)或欠采样(跳过帧)。如果您关心这一点,请尝试使用let reader = try! AVAssetReader(asset: asset) let videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] // read video frames as BGRA let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings:[String(kCVPixelBufferPixelFormatTypeKey): NSNumber(unsignedInt: kCVPixelFormatType_32BGRA)]) reader.addOutput(trackReaderOutput) reader.startReading() while let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() { if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) { // now you have images as CVImageBuffers/CVPixelBuffers process(imageBuffer) } } 来阅读视频中的所有相框:

CVPixelBuffer

这会将所有帧都显示为CMSampleBufferGetPresentationTimeStamp(sampleBuffer)。您可以使用代码like this轻松将它们转换为其他类型。如果您对帧的时间戳感兴趣,请致电 $foobar = $foo?->bar();