4

我可以使用 获取视频中的帧AVAssetImageGenerator,并且使用generateCGImagesAsynchronously. 每当结果成功时,我都会requestedTime以秒为单位打印该图像以及actualTime该图像的 。然而,最后,actualTimes即使我的步长值和时间帧间隔均匀,两个生成的图像也是相同的并且具有相同的。

这是我为每张图像打印的请求和实际时间的片段(以秒为单位):

Requested: 0.9666666666666667
Actual: 0.9666666666666667

Requested: 1.0
Actual: 1.0

Requested: 1.0333333333333334
Actual: 1.0333333333333334

Requested: 1.0666666666666667
Actual: 1.0666666666666667

Requested: 1.1
Actual: 1.1

Requested: 1.1333333333333333
Actual: 1.1

Requested: 1.1666666666666667
Actual: 1.135

在生成对应于视频中 1.1 秒的帧之前似乎一切正常,这会导致两个相同的图像,并且actualTime在其余过程中被延迟。

我已经尝试调整计算应该生成的帧的方式,但它似乎是正确的。我使用每秒帧数并将其乘以视频持续时间来计算我总共需要多少帧,并且我将总持续时间除以样本计数以确保均匀生成 cgImages。

let videoDuration = asset.duration
print("video duration: \(videoDuration.seconds)")
let videoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
let fps = videoTrack.nominalFrameRate
var frameForTimes = [NSValue]()
let sampleCounts = Int(videoDuration.seconds * Double(fps))
let totalTimeLength = Int(videoDuration.seconds * Double(videoDuration.timescale))
let step = totalTimeLength / sampleCounts
for i in 0 ..< sampleCounts {
     let cmTime = CMTimeMake(value: Int64(i * step), timescale: Int32(videoDuration.timescale))
     frameForTimes.append(NSValue(time: cmTime))
}

以及我创建图像的方式(见此):

imageGenerator.generateCGImagesAsynchronously(forTimes: timeValues) { (requestedTime, cgImage, actualTime, result, error) in
     if let cgImage = cgImage {
          print("Requested: \(requestedTime.seconds), Actual: \(actualTime.seconds)")
          let image = UIImage(cgImage: cgImage)
          // scale image if you want
          frames.append(image)
     }
}

在调用之前,我还将容差设置为零generateCGImages

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

我希望实际时间与请求的时间一致,并且每个生成的图像都不同。纵观图像,无论正在测试的视频如何,总是存在重复的,并且通常发生在中间到结尾。

编辑:

我发现thisthisthis都提到了同样的问题,但我没有成功。

4

0 回答 0