Swift 動画からキャプチャ画像を抽出する

動画ファイルから1秒単位でキャプチャ画像を生成するサンプルをメモしておく

import UIKit
import AVKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    var picker = UIImagePickerController()
    var scrollView = UIScrollView()

    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
        view.addSubview(scrollView)

        // フォトライブラリーから動画を取得
        picker.sourceType = UIImagePickerController.SourceType.photoLibrary
        picker.mediaTypes = ["public.movie"]
        picker.delegate = self
        present(picker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true, completion: nil)

        guard let videoURL = info[UIImagePickerController.InfoKey.mediaURL] as? URL else {
            return
        }

        var images = [UIImage]()

        let asset = AVAsset(url: videoURL)
        let duration = CMTimeGetSeconds(asset.duration)
        let generator = AVAssetImageGenerator(asset: asset)
        generator.appliesPreferredTrackTransform = true

        // 1秒毎にUIImageを生成
        for index: Int in 0 ..< Int(duration) {
            let floatTime = Float64(index)
            let time = CMTimeMakeWithSeconds(floatTime, preferredTimescale: 600)
            if let image = try? generator.copyCGImage(at: time, actualTime: nil) {
		images.append(UIImage(cgImage: image))
            }
	}

        // UIImageを画面に表示
        var y: CGFloat = 0
	let marginX: CGFloat = 50
        let marginY: CGFloat = 10

        for index: Int in 0 ..< images.count {

            let image = images[index]
            let width = view.frame.width - marginX*2
            let ratio = width / image.size.width
            let height = image.size.height * ratio

            let imageView = UIImageView(image: image)
            imageView.frame = CGRect(x: marginX, y: y, width: width, height: height)

            scrollView.addSubview(imageView)
            scrollView.contentSize = CGSize(width: view.frame.width, height: y + height)

            y = y + height + marginY
        }
    }
}

以上です