Прежде всего, мне нужно получить последний кадр видео, записанного с использованием 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)")
}
}