0

I need to split video(PHAsset) to frames. Please could anyone write an extension for PHAsset for example to call function like this:

extension PHAsset {
   func getFrame(timecode: Float) -> UIImage? {
      *something*
      return frame
   }
}

You can change parameters in below function. Help!

Sanzhar
  • 50
  • 6
  • Does this answer your question? [Swift - get all frames from video](https://stackoverflow.com/questions/42665271/swift-get-all-frames-from-video) – timbre timbre Sep 07 '22 at 17:17

1 Answers1

1

Try this:

import Photos

extension PHAsset {
    
    func getVideoFrames(completion: @escaping ([UIImage]?) -> Void) {
        guard self.mediaType == .video else { completion(nil); return }
        
        let manager = PHCachingImageManager()
        
        manager.requestAVAsset(forVideo: self, options: nil) { asset, audioMix, info in
            guard let asset = asset else { completion(nil); return }
            let imgGenerator: AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
            imgGenerator.appliesPreferredTrackTransform = true
            imgGenerator.requestedTimeToleranceBefore = CMTimeMake(value: 1, timescale: 15)
            imgGenerator.requestedTimeToleranceAfter = CMTimeMake(value: 1, timescale: 15)
            let duration: Float64 = CMTimeGetSeconds(asset.duration)
            var frames = [UIImage]()
            for index: Int in 0..<Int(duration) {
                let time: CMTime  = CMTimeMakeWithSeconds(Float64(index), preferredTimescale: 600)
                let cgImage: CGImage
                do {
                    try cgImage = imgGenerator.copyCGImage(at: time, actualTime: nil)
                    frames.append(UIImage(cgImage: cgImage))
                } catch {
                    print("Error generating image: \(error)")
                }
            }
            completion(frames)
        }
    }
}

Usage:

let asset = // Some PHAsset
var frames = [UIImage]()
asset.getVideoFrame { images in 
    if let images = images {
        frames = images
        // Do something
    }
}

Asteroid
  • 1,049
  • 2
  • 8
  • 16
  • thanks you, but I follow 1 bug every video, when I'm trying to split my video to frames array of images contains several identical pictures, that is, the first 3 pictures from the video seem is the same, although in reality they are very different – Sanzhar Sep 08 '22 at 09:22
  • 1
    I edited the answer. Please try it. – Asteroid Sep 08 '22 at 14:33