generateCGImagesAsynchronically создает дубликаты изображений в соответствии с фактическим временем - PullRequest
3 голосов
/ 18 октября 2019

Я могу получить кадры из видео, используя 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

Я ожидал, что фактическое время будет соответствовать запрошенному времени, и для каждого получаемого изображения будет разным. Просматривая изображения, всегда есть дубликат, независимо от того, какое видео тестируется, и обычно это происходит к середине.

Редактировать:

Я нашел это , это и это , в которых упоминается та же проблема, но я не добился успеха ни с одним из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...