根据文档,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帧/秒),但第1帧的帧每次重复10次。当请求1秒时返回帧时间为0.1秒。
P.S:虽然同步方法工作正常,但需要两倍的时间 异步方法所花费的时间。可能是因为它正在回归 相同的帧。但我需要它来检查实际的使用时间。
答案 0 :(得分:1)
您需要将requestedTimeToleranceBefore
和requestedTimeToleranceAfter
设置为所需的精度,例如.zero
,但这可能会导致额外的延迟和生成图像的成本。
例如:
imageGenerator.requestedTimeToleranceBefore = .zero
imageGenerator.requestedTimeToleranceAfter = .zero
这样,您将在那时获得准确的帧。
答案 1 :(得分:0)
不确定原因,但是当从主线程调用该函数时,我得到了错误。但是当我从后台线程调用它时,它就开始工作了。
不确定解释,但在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
}))
}