Как получить последний кадр AVKit записанного видео с максимальным пределом записи - PullRequest
0 голосов
/ 11 апреля 2019

Прежде всего, мне нужно получить последний кадр видео, записанного с использованием AVKit. Итак, в методе делегата didFinishRecordingTo, который дает мне outputFileURL, я использую метод AVAssetImageGenerator's copyCGImage с параметром time, равным videoAsset.duration.

Моя запись видео имеет ограничение в 5 секунд, установленное в AVCaptureMovieFileOutput.maxRecordedDuration, что является « жестким ограничением », как указано в документации Apple, что означает (после тестирования), что запись видео никогда не достигнет ровно 5 с и он остановится раньше, то есть 4.90123 с. Я также использую requestedTimeToleranceBefore и requestedTimeToleranceAfter, установленные на kCMTimeZero, чтобы иметь возможность получить именно этот последний кадр, потому что без них это даст мне совершенно другой кадр.

Пока все хорошо. Когда я прекращаю запись в любое время <= 5 с, поэтому предел еще не достигнут, метод copyCGImage успешно возвращает мой cgImage. Это не тот случай, когда я нажимаю maxRecordedDuration, когда метод copyCGImage выдает исключение с сообщением «Cannot Open» каждый раз. Этого не произойдет, если я уберу эти 2 параметра допуска, которые дают мне точный последний кадр, но мне нужно, чтобы они были там. </p>

Почему это происходит? В чем разница с достигнутым и недостигнутым пределом записанного видеофайла? Похоже, что когда предел достигнут, последние несколько кадров ломаются и не могут быть использованы. Но, в любом случае, есть ли четкое объяснение этому? Кто-нибудь еще сталкивался с этой проблемой? Как я могу решить это?

Вывод и ясный вопрос: как получить последний кадр записанного видео с помощью AVKit, когда достигнут предел maxRecordedDuration?

Заранее спасибо.

Пример кода ниже:

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    let videoAsset = AVURLAsset(url: outputFileURL)
    let imageGenerator = AVAssetImageGenerator(asset: videoAsset)
    imageGenerator.appliesPreferredTrackTransform = true
    imageGenerator.requestedTimeToleranceBefore = kCMTimeZero
    imageGenerator.requestedTimeToleranceAfter = kCMTimeZero

    let time = CMTime(seconds: videoAsset.duration.seconds - durationToCheck, preferredTimescale: videoAsset.duration.timescale)

    var cgImage: CGImage?
    do {
        cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
    } catch {
        print("Error generating image with error: \(error.localizedDescription)")
    }
}
...