前提・実現したいこと
カメラロールから画像や動画の取得後、サムネイルを生成と動画の場合は再生まで行えるようにしたいと考えています。
発生している問題・エラーメッセージ
エラーメッセージ Unexpectedly found nil while unwrapping an Optional value imageView.image = previewImageFromVideo(videoURL!)! のところで上記のエラーが出ます。
該当のソースコード
Swift
1ソースコード 2import UIKit 3import AVKit 4import AVFoundation 5 6class UploadViewController: UIViewController { 7 let imagePickerController = UIImagePickerController() 8 var videoURL: URL? 9 10 11 @IBOutlet weak var imageView: UIImageView! 12 13 14 @IBOutlet weak var selectButton: UIButton! 15 16 @IBOutlet weak var playButtton: UIButton! 17 18 19 @IBAction func selectImage(_ sender: Any) { 20 print("UIBarButtonItem。カメラロールから動画を選択") 21 imagePickerController.sourceType = .photoLibrary 22 imagePickerController.delegate = self 23 imagePickerController.mediaTypes = ["public.image", "public.movie"] 24 25 present(imagePickerController, animated: true, completion: nil) 26 27 } 28 29 30 31 32 override func viewDidLoad() { 33 super.viewDidLoad() 34 } 35} 36 37 extension UploadViewController: UINavigationControllerDelegate,UIImagePickerControllerDelegate{ 38 39 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 40 print("cancel") 41 } 42 43 44 45 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 46 47 videoURL = info[.referenceURL] as? URL 48 print(videoURL!) 49 imageView.image = previewImageFromVideo(videoURL!)! 50 imageView.contentMode = .scaleAspectFit 51 imagePickerController.dismiss(animated: true, completion: nil) 52 53 } 54 55 56 func previewImageFromVideo(_ url:URL) -> UIImage? { 57 58 print("動画からサムネイルを生成する") 59 let asset = AVAsset(url:url) 60 let imageGenerator = AVAssetImageGenerator(asset:asset) 61 imageGenerator.appliesPreferredTrackTransform = true 62 var time = asset.duration 63 time.value = min(time.value,2) 64 do { 65 let imageRef = try imageGenerator.copyCGImage(at: time, actualTime: nil) 66 return UIImage(cgImage: imageRef) 67 } catch { 68 return nil 69 } 70 } 71 72 73 74 @IBAction func playMovie(_ sender: Any) { 75 if let videoURL = videoURL{ 76 let player = AVPlayer(url: videoURL) 77 let playerViewController = AVPlayerViewController() 78 playerViewController.player = player 79 present(playerViewController, animated: true){ 80 print("動画再生") 81 playerViewController.player!.play() 82 } 83 } 84 85 } 86 87 } 88 89
試したこと
こちらのサイトとこちらの質問を参考にエラーに対応したのですが、実機でテストを行った際にエラーコードが出てしまいました。
動画の圧縮が行われていることと「動画からサムネイルを生成する」というテキストがprintされることは確認できました。
リンク先を見ればわかるようにもともと
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
となっていたところを
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
に変更後
videoURL = info["UIImagePickerControllerReferenceURL"] as? URL print(videoURL!)
の部分でエラーが出たため
videoURL = info[.referenceURL] as? URL print(videoURL!)
に変更しました。
ここまで行って実行したところ「動画からサムネイルを生成する」のテキストが表示され、質問のエラーが起こることを確認しました。
また、takabosoft様のアドバイスをもとに追記したところ「開けません」というメッセージが返ってきました。
たぶん
try imageGenerator.copyCGImage(at: time, actualTime: nil)
で例外が出て、
return nilの方に行っていると思うので、
catch let error as NSError {
print(error.localizedDescription)
}
などとNSErrorをキャッチしてエラーの中身を表示してみてはいかがでしょうか。
imagePickerController.mediaTypes = ["public.image", "public.movie"]
という感じで動画だけでなく写真も選べるようですが、写真のアセットに対してpreviewImageFromVideoを呼び出しているという事は無いでしょうか?
あなたの回答
tips
プレビュー