動画からサムネイルを生成する | Swift3.0

on.gif

説明

まだ動画を選択してないとnilで落ちる。

使い用途

動画をトリミングする時のUIが作れたり

実装

import UIKit
import AVKit
import AVFoundation

var int = 0

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    let imagePickerController = UIImagePickerController()
    var videoURL: URL?


    @IBOutlet weak var imageView: UIImageView!
    @IBAction func selectImage(_ sender: Any) {
        print("UIBarButtonItem。カメラロールから動画を選択")
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.delegate = self
        //imagePickerController.mediaTypes = ["public.image", "public.movie"]
        //動画だけ
        imagePickerController.mediaTypes = ["public.movie"]
        //画像だけ
        //imagePickerController.mediaTypes = ["public.image"]
        present(imagePickerController, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // 一つめのスライダー
        let startPointSlider = UISlider(frame: CGRect(x:0, y:0, width:350, height:30))
        startPointSlider.layer.position = CGPoint(x:self.view.frame.midX, y:500)
        startPointSlider.backgroundColor = UIColor.white
        startPointSlider.layer.cornerRadius = 10.0
        startPointSlider.layer.shadowOpacity = 0.5
        startPointSlider.layer.masksToBounds = false
        startPointSlider.addTarget(self, action: #selector(self.onStartPointlabel(_:)), for: .valueChanged)

        // 最小値と最大値を設定する.
        startPointSlider.minimumValue = 0
        startPointSlider.maximumValue = 100

        self.view.addSubview(startPointSlider)

        //一つめのラベル
        let startPointlabel = UILabel()
        startPointlabel.text = "start point"
        startPointlabel.sizeToFit()
        startPointlabel.layer.position = CGPoint(x:self.view.frame.midX, y:450)
        self.view.addSubview(startPointlabel)

        // 二つめのスライダー
        let endPointSlider = UISlider(frame: CGRect(x:0, y:0, width:350, height:30))
        endPointSlider.layer.position = CGPoint(x:self.view.frame.midX, y:600)
        endPointSlider.backgroundColor = UIColor.white
        endPointSlider.layer.cornerRadius = 10.0
        endPointSlider.layer.shadowOpacity = 0.5
        endPointSlider.layer.masksToBounds = false
        endPointSlider.addTarget(self, action: #selector(self.onEndPointlabel(_:)), for: .valueChanged)

        // 最小値と最大値を設定する.
        endPointSlider.minimumValue = 0
        endPointSlider.maximumValue = 100

        self.view.addSubview(endPointSlider)

        //二つめのラベル
        let endPointlabel = UILabel()
        endPointlabel.text = "end point"
        endPointlabel.sizeToFit()
        endPointlabel.layer.position = CGPoint(x:self.view.frame.midX, y:550)
        self.view.addSubview(endPointlabel)
    }

    /*
     Sliderの値が変わった時に呼ばれるメソッド
     */

    func onStartPointlabel(_ sender:UISlider!)
    {
        print(floor(sender.value))
        int = Int(floor(sender.value))
        imageView.image = previewImageFromVideo(videoURL!)!

    }

    func onEndPointlabel(_ sender:UISlider!)
    {
        print(floor(sender.value))
        int = Int(floor(sender.value))
        imageView.image = previewImageFromVideo(videoURL!)!

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        videoURL = info["UIImagePickerControllerReferenceURL"] as? URL
        print(videoURL!)
        imageView.image = previewImageFromVideo(videoURL!)!
        imageView.contentMode = .scaleAspectFit
        imagePickerController.dismiss(animated: true, completion: nil)

    }

    func previewImageFromVideo(_ url:URL) -> UIImage? {
        print("動画からサムネイルを生成する")
        let asset = AVAsset(url:url)
        let imageGenerator = AVAssetImageGenerator(asset:asset)
        imageGenerator.appliesPreferredTrackTransform = true
        var time = asset.duration
        time.value = min(30,32)
        do {
            let imageRef = try imageGenerator.copyCGImage(at: CMTimeMake(Int64(int), 1), actualTime: nil)
            return UIImage(cgImage: imageRef)
        } catch {
            return nil
        }
    }
}

ソース

GiyHub

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事