1

根据文档,generateCGImagesAsynchronously接收一个数组NSValue并从视频和给定时间生成帧,并将其作为回调返回。

我使用以下代码生成值列表

    var values : [NSValue] = []
    let frameDuration = CMTimeMake(1, timeScale)
    for i in 0..<duration{
        let lastFrameTime = CMTimeMake(Int64(i), timeScale)
        let presentationTime = (i == 0) ? lastFrameTime : CMTimeAdd(lastFrameTime, frameDuration)

        values.append(NSValue(time: presentationTime))

        //Next two lines of codes are just to cross check the output
        let image = try! imageGenerator.copyCGImage(at: presentationTime, actualTime: nil)
        let imageUrl = FileManagerUtil.getTempFileName(parentFolder: FrameExtractor.EXTRACTED_IMAGE, fileNameWithExtension: "\(Constants.FRAME_SUFFIX)\(i)\(".jpeg")")
    }

正如您在上面的代码中看到的,我使用同步方法交叉检查了结果,我可以确认values数组持有正确的时间参考。

但是当相同的数组传递给generateImageAsynchronously方法时,我会为不同的时间戳重复 10 次相同的帧。也就是说,如果我的视频是 10 秒,那么我会得到 300 帧(30 fps),但第一秒的帧每个重复 10 次。当请求 1 秒时,它类似于以 0.1 秒的时间返回帧。

PS:虽然同步方法工作正常,但它所花费的时间是异步方法的两倍。可能是因为它返回相同的帧。但我需要它来检查实际的时间使用情况。

4

2 回答 2

3

例如,您需要设置requestedTimeToleranceBeforerequestedTimeToleranceAfter达到您想要的精度,.zero但这可能会产生额外的延迟和生成图像的成本。

例如:

imageGenerator.requestedTimeToleranceBefore = .zero
imageGenerator.requestedTimeToleranceAfter = .zero

这样,您将获得当时的确切帧。

于 2019-10-05T23:32:47.247 回答
2

不知道为什么,但是当从主线程调用函数时,我得到了这个错误。但是当我从后台线程调用它时,它就开始工作了。

不确定解释,但下面的 Swift4 代码似乎正在工作,并且与单个帧提取相比要快得多,例如let image = imageGenerator.copyCGImage(at: time, actualTime: nil)

DispatchQueue.global(qos: .background).async {
    imageGenerator.generateCGImagesAsynchronously(forTimes: localValue, completionHandler: ({ (startTime, generatedImage, endTime, result, error) in
        //Save image to file or perform any task
    }))
}
于 2018-05-24T05:59:45.917 回答