【Swift】動画撮影&保存&取得【UIImagePickerController】
やりたいこと
アプリ内で動画を撮影し保存。
また、アプリ内で撮影した動画のみを取得。
実装方法
動画撮影
動画周りはややこしいイメージがあったが、
UIImagePickerController
を使えば意外と簡単に実装できた。
let sourceType = UIImagePickerController.SourceType.camera // 端末でカメラが利用可能か調べる if UIImagePickerController.isSourceTypeAvailable(sourceType) { let pickerController = UIImagePickerController() pickerController.delegate = self pickerController.sourceType = sourceType // ここで動画を選択 pickerController.mediaTypes = ["public.movie"] // 以下のようにすると、利用可能な全てのmediaTypeが選択できる // pickerController.mediaTypes = UIImagePickerController.availableMediaTypes(for: sourceType) ?? [] // 動画を高画質で保存する pickerController.videoQuality = .typeHigh present(pickerController, animated: true, completion: nil) }
動画保存
撮影した動画はAppData内のtmpフォルダ(一時フォルダ)に置かれているので、
Documentフォルダに移動する。
カメラロールに保存するよりもアプリ内動画一覧の取得が実装しやすい。
あとで必要なものだけカメラロールにエクスポートする方法をとった。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { picker.dismiss(animated: true, completion: nil) // 一時フォルダに保存されたファイルのURL guard let fileUrl = info[.mediaURL] as? URL else { return } // DocumentフォルダのURL let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! do { // tmpに保存された動画をDocumentに移動 try FileManager.default.moveItem(at: fileUrl, to: documentsDirectoryURL.appendingPathComponent(fileUrl.lastPathComponent)) print("動画の保存に成功しました。") } catch { print("動画の保存に失敗しました。") } }
動画取得
Documentフォルダ内のファイルのURLを全て取得する。
var videoUrls = [URL]() let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! do { // Documentから動画ファイルのURLを取得 videoUrls = try FileManager.default.contentsOfDirectory(at: documentDirectoryURL, includingPropertiesForKeys: nil) } catch { print("フォルダが空です。") }
取得したURLを使って、動画を再生したり、一覧を表示したりできる。
Collection Viewにサムネイル一覧を表示するならこんな感じ。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) // URLから動画を取得 let video = AVURLAsset(url: videoUrls[indexPath.row]) // 動画から静止画を切り出すジェネレータ let generator = AVAssetImageGenerator(asset: video) // 今回は00:00の部分を切り出し let thumbnail = try! generator.copyCGImage(at: .zero, actualTime: nil) let thumbnailView = cell.viewWithTag(1) as! UIImageView thumbnailView.image = UIImage(cgImage: thumbnail) let label = cell.viewWithTag(2) as! UILabel let sec = Int(video.duration.seconds) label.text = String(format:"%02d:%02d", sec/60, sec%60) return cell }