如何知道generateCGImages异步完成的时间?
问题描述:
我有一个需要拍摄视频,将每帧转换为图像并将这些图像保存到磁盘。我想使用AVAssetImageGenerator
效率的缘故,并有类似的代码如下:如何知道generateCGImages异步完成的时间?
的问题是,我不知道什么时候所有图像生成完成,但我需要采取行动,一旦所有帧写入磁盘。例如:
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
})
这是上面的第2步,让我绊倒。我想我可以尝试计算完成处理程序被调用的次数,并在计数等于帧数时触发适当的方法。
但我想知道是否有一种方法来使用API来知道每一帧的处理?也许只是我错过了什么?任何指导或建议,将不胜感激。
答
我会逐步处理图像,无论如何您都无法将它们全部放入内存中。为此,您可以使用assetGenerator.copyCGImageAtTime
在特定时间对视频进行采样。
但是,你可能过采样(重复帧)或欠采样(跳帧)。如果你关心这一点,那么请尝试使用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
秒。您可以使用代码like this轻松将它们转换为其他类型。如果您对帧的时间戳感兴趣,请致电CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
。
谢谢,这看起来像一个更好的解决方案。 – terrafirma9
很好的答案。有用。 – Leo