WEBサイト制作・アプリ開発・システム開発・ブランディングデザイン制作に関するご相談はお気軽にご連絡ください。
構想段階からじっくりとヒアリングし、お客様の課題にあわせたアプローチ手法でお客様の“欲しかった”をカタチにしてご提案いたします。
Blog スタッフブログ
Swift
システム開発
[iOS]選択した動画ファイルの指定秒のサムネイルを取得する
こんにちは、株式会社MIXシステム開発担当のBloomです。
早速本題の選択した動画ファイルの指定秒のサムネイル画像を取得する手順について、
お仕事の中で得た知見を共有させていただきたいと思います。
Androidでサムネイル生成はこちら
JavaScriptでサムネイル生成はこちら
動画ファイルの選択
今回はUIImagePickerではなくPHPickerViewControllerを利用して動画ファイルを選択します。
import PhotosUI
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
@IBAction func selectButtonTouchUpInside(_ sender: Any) {
// ライブラリ権限取得 別途Privacy - Photo Library Usage Descriptionの設定を行なってください
if PHPhotoLibrary.authorizationStatus() != .authorized {
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .notDetermined, .denied:
self.appearChangeStatusAlert()
case .authorized:
self.showPicker()
default:
break
}
}
}
else {
showPicker()
}
}
private func appearChangeStatusAlert() {
// アクセス権限が取れなかった場合に表示
let alert = UIAlertController(title: "ライブラリが開けませんでした", message: "設定からフォトライブラリへのアクセスを許可してください", preferredStyle: .alert)
let settingAction = UIAlertAction(title: "設定", style: .default, handler: { (_) in
guard let settingUrl = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(settingUrl, options: [:], completionHandler: nil)
})
let closeAction = UIAlertAction(title: "キャンセル", style: .cancel, handler: nil)
alert.addAction(settingAction)
alert.addAction(closeAction)
self.present(alert, animated: true, completion: nil)
}
private func showPicker() {
// PHPickerViewControllerを表示
DispatchQueue.main.async {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.filter = .videos
configuration.selectionLimit = 1
configuration.preferredAssetRepresentationMode = .current
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
}
}
}
サムネイルを取得
PHPickerViewControllerDelegateから動画ファイルを受け取り、AVAssetを経由して静止画を取得します。
extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
guard let provider = results.first?.itemProvider else { return }
guard let typeIdentifier = provider.registeredTypeIdentifiers.first else { return }
picker.dismiss(animated: true, completion: nil)
if provider.hasItemConformingToTypeIdentifier(typeIdentifier) {
provider.loadFileRepresentation(forTypeIdentifier: typeIdentifier) { (url, error) in
if let error = error { print("*** error: \(error)") }
if let url = url {
// サムネイル生成
let avAsset = AVAsset(url: url)
let generator = AVAssetImageGenerator(asset: avAsset)
generator.appliesPreferredTrackTransform = true
generator.requestedTimeToleranceAfter = .zero
generator.requestedTimeToleranceBefore = .zero
let duration = avAsset.duration
let seconds = 5.0 // 5秒で指定
let time = CMTime(seconds: seconds, preferredTimescale: duration.timescale)
let capturedImage = try! generator.copyCGImage(at: time, actualTime: nil)
let image = UIImage(cgImage: capturedImage)
DispatchQueue.main.async {
// 取得したimageを表示
self.imageView.image = image
}
}
}
}
}
}
実行結果
これで簡単にサムネイルが生成できました。良かったですね。