Sam007
Sam007

Reputation: 1405

How to show only spatial video using PHPickerFilter?

I want to get only spatial video while open the Photo library in my app. How can I achieve?

One more thing, If I am selecting any video using photo library then how to identify selected video is Spatial Video or not?

self.presentPicker(filter: .videos)


/// - Tag: PresentPicker
private func presentPicker(filter: PHPickerFilter?) {
    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 multiselection.
    configuration.selectionLimit = 1
    
    let picker = PHPickerViewController(configuration: configuration)
    picker.delegate = self
    present(picker, animated: true)
}

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true) {
        // do something on dismiss
    }
    
    guard let provider = results.first?.itemProvider else {return}
    provider.loadFileRepresentation(forTypeIdentifier: "public.movie") { url, error in
        guard error == nil else{
            print(error)
            return
        }
        // receiving the video-local-URL / filepath
        guard let url = url else {return}
        // create a new filename
        let fileName = "\(Int(Date().timeIntervalSince1970)).\(url.pathExtension)"
        // create new URL
        let newUrl = URL(fileURLWithPath: NSTemporaryDirectory() + fileName)
        
        print(newUrl)
        print("===========")

    }
}

Upvotes: 1

Views: 165

Answers (2)

Mitch Cohen
Mitch Cohen

Reputation: 1645

As of iOS 18/VisionOS 2/macOS 15, .spatialMedia is a PHPickerFilter option.

Filters can be combined. To show only spatial videos in the picker:

let filter = PHPickerFilter.all(of: [.videos, .spatialMedia])

then per the example in the original question:

self.presentPicker(filter: filter)

Upvotes: 1

Jack Guo
Jack Guo

Reputation: 4714

Updated June 2024

In visionOS 2, you can filter for spatialMedia. But it includes spatial photos too.

You can now also check if a video is spatial or not by

extension AVURLAsset {
  func isSpatialVideo() async -> Bool {
    let assistant = AVAssetPlaybackAssistant(asset: self)
    let options = await assistant.playbackConfigurationOptions
    return options.contains(.spatialVideo)
  }
}

Original post

It's currently not supported as of Apr 2024. The best you can do is to filter for videos.

To check whether a video is spatial, you can do

if let _ = try? await AVURLAsset(url: videoURL).loadTracks(withMediaCharacteristic: .containsStereoMultiviewVideo).first {
  print("Is spatial video")
} else {
  print("Is not a spatial video")
}

Reference: https://developer.apple.com/documentation/avfoundation/media_reading_and_writing/reading_multiview_3d_video_files#4332053

Upvotes: 1

Related Questions