From Camera Roll
VideoEditor SDK supports importing videos from the camera roll.
Instantiate image picker#
To that end, we first instantiate a UIImagePickerController
. We are opting for this class over PHPickerViewController
, because the latter does not reliably work for some .mp4
files encoded with non-ffmpeg codecs.
We have reported this issue to Apple.
We further set the current class as the controller's delegate to handle cancellation. Since we only want videos from the camera roll, we set sourceType
and mediaType
correspondingly.
Prevent re-encoding#
We want to prevent reencoding the video when UIImagePickerController
passes it to the delegate methods, so we set the videoExportPreset
property to passthrough
Initialize the editor#
The imagePickerController
delegate is invoked when the user picked a video and the video's mediaURL
is passed to it via the info dictionary.
We can now dismiss the image picker and create a Video
from the videoURL
which is in turn passed as videoAsset
to the VideoEditViewController
to instantiate the video editor.
Again, setting the current class as the delegate of the VideoEditViewController
allows us to implement export, cancellation and error handling there.
import AVFoundationimport Foundationimport UniformTypeIdentifiersimport VideoEditorSDKclass OpenVideoFromCameraRollSwift: Example, UIImagePickerControllerDelegate, UINavigationControllerDelegate, VideoEditViewControllerDelegate {override func invokeExample() {// We recommend using the old `UIImagePickerController` class instead of the newer `PHPickerViewController`// due to video import issues for some MP4 files encoded with non-ffmpeg codecs. We've filed a bug report// with Apple regarding this issue.let imagePicker = UIImagePickerController()imagePicker.delegate = selfimagePicker.sourceType = UIImagePickerController.SourceType.photoLibraryimagePicker.mediaTypes = [UTType.movie.identifier]// Setting `videoExportPreset` to passthrough will not reencode the video before passing it to// the delegate methods.imagePicker.videoExportPreset = AVAssetExportPresetPassthrough// Present the image picker modally.imagePicker.modalPresentationStyle = .fullScreenpresentingViewController?.present(imagePicker, animated: true, completion: nil)}// MARK: - UIImagePickerControllerDelegatefunc imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {guard let videoURL = info[.mediaURL] as? URL else {fatalError()}// Dismiss the image picker and present the video editor after dismissal is donepresentingViewController?.dismiss(animated: true, completion: {// Create a `Video` from the picked video URLlet video = Video(url: videoURL)// Create a video editor and pass it the video. Make this class the delegate of it to handle export and cancelation.let videoEditViewController = VideoEditViewController(videoAsset: video)videoEditViewController.delegate = self// Present the video editor.videoEditViewController.modalPresentationStyle = .fullScreenself.presentingViewController?.present(videoEditViewController, animated: true, completion: nil)})}func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {presentingViewController?.dismiss(animated: true, completion: nil)}// MARK: - VideoEditViewControllerDelegatefunc videoEditViewControllerShouldStart(_ videoEditViewController: VideoEditViewController, task: VideoEditorTask) -> Bool {// Implementing this method is optional. You can perform additional validation and interrupt the process by returning `false`.true}func videoEditViewControllerDidFinish(_ videoEditViewController: VideoEditViewController, result: VideoEditorResult) {// The user exported a new video successfully and the newly generated video is located at `result.output.url`. Dismissing the editor.presentingViewController?.dismiss(animated: true, completion: nil)}func videoEditViewControllerDidFail(_ videoEditViewController: VideoEditViewController, error: VideoEditorError) {// There was an error generating the video.print(error.localizedDescription)// Dismissing the editor.presentingViewController?.dismiss(animated: true, completion: nil)}func videoEditViewControllerDidCancel(_ videoEditViewController: VideoEditViewController) {// The user tapped on the cancel button within the editor. Dismissing the editor.presentingViewController?.dismiss(animated: true, completion: nil)}}