简体   繁体   English

我怎么知道 generateCGImagesAsynchronously 何时完全完成?

[英]How do I know when generateCGImagesAsynchronously has completely finished?

I have a requirement to take a video, convert each frame to and image and save these images to disk.我需要拍摄视频,将每一帧转换为图像并将这些图像保存到磁盘。 I'd like to use AVAssetImageGenerator for efficiency's sake, and have code similar to the following:我想使用AVAssetImageGenerator以提高效率,并具有类似于以下的代码:

The issue is that I don't know when all image generation is complete, but I need to take action once all frames are written to disk.问题是我不知道所有图像生成何时完成,但是一旦所有帧都写入磁盘,我需要采取行动。 For example:例如:

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
})

It's step 2 above that's tripping me up.上面的第 2 步让我绊倒了。 I imagine I can try to count the number of times the completion handler gets called, and trigger the appropriate method when the count equals the number of frames.我想我可以尝试计算调用完成处理程序的次数,并在计数等于帧数时触发适当的方法。

But I'm wondering if there's a way to use the API to know when every frame has been processed?但我想知道是否有一种方法可以使用 API 来知道何时处理了每一帧? Maybe just something I've missed?也许只是我错过了什么? Any guidance or advice would be appreciated.任何指导或建议将不胜感激。

I would progressively process the images, you won't be able to fit them all in memory at once anyway.我会逐步处理图像,无论如何您都无法一次将它们全部放入内存中。 To do that you could sample the video at certain times using assetGenerator.copyCGImageAtTime .为此,您可以使用assetGenerator.copyCGImageAtTime在特定时间对视频进行assetGenerator.copyCGImageAtTime

But then you may oversample (repeating frames) or undersample (skipping frames).但是你可能会过度采样(重复帧)或采样不足(跳帧)。 If you care about that, then try using AVAssetReader to read all the frames in the video:如果您关心这一点,请尝试使用AVAssetReader读取视频中的所有帧:

    let reader = try! AVAssetReader(asset: asset)

    let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]

    // read video frames as BGRA
    let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings:[String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)])

    reader.add(trackReaderOutput)
    reader.startReading()

    while let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
        if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
            // now you have images as CVImageBuffers/CVPixelBuffers
            process(imageBuffer)
        }
    }

This gives you all the frames as CVPixelBuffer s.这将为您提供所有帧作为CVPixelBuffer s。 You can easily convert them to other types using code like this .您可以轻松地将它们转换为其他类型的使用代码这样 If you're interested in the timestamp of the frames, call CMSampleBufferGetPresentationTimeStamp(sampleBuffer) .如果您对帧的时间戳感兴趣,请调用CMSampleBufferGetPresentationTimeStamp(sampleBuffer)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Swift:generateCGImagesAsynchronously 完成后如何加载结果? - Swift: How to load results after generateCGImagesAsynchronously is finished? 如何知道UICollectionView何时完成布局? - How to know when UICollectionView has finished layout? 如何检测UIWebView何时完全加载? - How to detect when a UIWebView has completely finished loading? 如何知道/测试动画何时完成播放 - How to know/test when an animation has finished playing 如何知道AVSpeechUtterance何时完成,以便继续进行应用程序活动? - How to know when an AVSpeechUtterance has finished, so as to continue app activity? 如何检测AVCaptureDevice的闪光灯何时完成并且静止图像拍摄已开始? - How do I detect when the flash for the AVCaptureDevice has finished and still image capture has begun? 我如何使用此异步函数的回调参数来了解我的 function 何时完成执行? - How do I use this async function's callback parm to know when my function finished executing? 我怎么知道什么时候在 UIWebView 中粘贴了一些东西? - How do I know when something has been pasted in a UIWebView? 我怎么知道UIWebView何时退出全屏? - How do I know when a UIWebView has exited full screen? 我怎么知道AVPlayer视频何时结束? - How do I know when an AVPlayer video has ended?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM