Search code examples
iosswiftphotophotosui

Is it possible to limit the video duration when selecting a video using `PHPickerViewController`?


Im attempting to select assets using PHPickerViewController as a replacement for my UIImagePickerController, however when setting the filter and config options Im not seeing a way to set a limit on the length of video that is returned. i.e. the way one may have done using a UIImagePickerController through videoMaximumDuration.

Has anyone found any sort of workout?

private func presentPicker(filter: PHPickerFilter?)-> PHPickerViewController {
    var configuration = PHPickerConfiguration(photoLibrary: .shared())
    
    // Set the filter type according to the user’s selection.
    configuration.filter = filter
    // Set the mode to avoid transcoding, if possible, if your app supports arbitrary image/video encodings.
    configuration.preferredAssetRepresentationMode = .current
    // Set the selection behavior to respect the user’s selection order.
    configuration.selection = .ordered
    // Set the selection limit to enable singular selection.
    configuration.selectionLimit = 1
    // Set the preselected asset identifiers with the identifiers that the app tracks.
    configuration.preselectedAssetIdentifiers = []
    
    let picker = PHPickerViewController(configuration: configuration)
    //picker.delegate = self
    //present(picker, animated: true)
    return picker
}

Solution

  • Having a look at the documentation for PHPickerFilter and the PHPickerViewController I can't see any native way to filter by video length.

    The best solution that I can think of to conform to the delegate PHPickerViewControllerDelegate and check the video length after the user has selected it.

    You haven't provided the rest of your code but you should conform to the PHPickerViewControllerDelegate and implement the required method:

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
          func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
           guard let provider = results.first?.itemProvider else { return }
           provider.loadItem(forTypeIdentifier: UTType.movie.identifier, options: [:]) { (videoURL, error) in
               // Check the video length here
           }
       }
    }
    

    See the above code for an example on how to load the video. From here you can follow some of the existing answers to see how to extract the video duration. If the video duration is within the bounds you want to filter for, copy it to an appropriate location using FileManager and process it how you see fit, if it does not (IE it is too long, or too short for your liking), then discard it and tell the user using an alert / message.

    Here is an example on how to get the duration of a video. Note: You just need to replace the references to urls to the videoURL you have access to in the completion handler (See the comment).

    Get the accurate duration of a video

    One other solution is to use a more powerful photo picker from a 3rd party.

    This has the downside of requiring the user to provide permission to their whole photo library (where as photo picker does not need to prompt for permission, as it is an iOS provided & sandboxed view controller). It also introduces another dependency into your app.

    If these downside are okay for your use case, then this might be just what you're looking for.

    Here is a library that provides some more powerful filters: https://github.com/Yummypets/YPImagePicker

    See the "Video" section on the README. It allows you to specify minimum and maximum video duration.