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
}
}
}以上です