Неправильные кадры от AVAssetImageGenerator.generateCGImagesAsynchronically - PullRequest
0 голосов
/ 23 мая 2018

Согласно документу, 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 раз каждый.Это похоже на возврат кадра в течение 0,1 секунды при запросе в течение 1 секунды.

PS: хотя синхронный метод работает нормально, он занимает вдвое больше времени, чем асинхронный метод.Может быть потому, что он возвращает те же кадры.Но мне нужно, чтобы он работал для проверки фактического использования времени.

1 Ответ

0 голосов
/ 24 мая 2018

Не знаю почему, но при вызове функции из основного потока я получаю сообщение об ошибке.Но когда я вызываю его из фонового потока, он начинает работать.

Не уверен насчет объяснения, но ниже Swift4 код работает и работает намного быстрее по сравнению с извлечением отдельных кадров, например let image = imageGenerator.copyCGImage(at: time, actualTime: nil)* 1004.*

DispatchQueue.global(qos: .background).async {
    imageGenerator.generateCGImagesAsynchronously(forTimes: localValue, completionHandler: ({ (startTime, generatedImage, endTime, result, error) in
        //Save image to file or perform any task
    }))
}
...