Get the last frame from the video
I am trying to get the last frame from a video. The last frame, not the last second (because I have very fast videos, one second can have different scenes).
I wrote code like this for testing:
private func getLastFrame(from item: AVPlayerItem) -> UIImage? {
let imageGenerator = AVAssetImageGenerator(asset: item.asset)
imageGenerator.requestedTimeToleranceAfter = kCMTimeZero
imageGenerator.requestedTimeToleranceBefore = kCMTimeZero
let composition = AVVideoComposition(propertiesOf: item.asset)
let time = CMTimeMakeWithSeconds(item.asset.duration.seconds, composition.frameDuration.timescale)
do {
let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
return UIImage(cgImage: cgImage)
} catch {
print("\(error)")
return nil
}
}
But I always get this error when trying to execute it:
Domain = AVFoundationErrorDomain Code = -11832 "Unable to open" UserInfo = {NSUnderlyingError = 0x170240180 {Domain = NSOSStatusErrorDomain Code = -12431 "(null)"}, NSLocalizedFailureReason = This media cannot be used to open.} NSLocalizedDesc
If I remove requestedTimeTolerance
(so it defaults to infinite), everything is fine, but I always get a brighter image than what I have in the video (maybe this is because the last frame was not captured? Or CGImage -> UIImage transform there are some problems?)
Questions:
- Why am I getting an error when setting a zero tolerance? How do I get the last frame?
-
Why might the captured images be overbrighted that in the video? For example, if I write code like this:
self.videoLayer.removeFromSuperlayer() self.backgroundImageView.image = getLastFrame(from: playerItem)
I see a "brightness transition" (the video was darker, the image was brighter).
Update 1
I found a related issue: AVAssetImageGenerator fails when copying an image , but this issue is not resolved.
source to share
No one has answered this question yet
See similar questions:
or similar: