PHPicker 加载视频

问题描述 投票:0回答:1

我正在尝试弄清楚如何使用 PHPicker 加载视频。我知道如何处理图像,但我似乎不知道如何处理视频。此代码仅适用于某些视频,不适用于其他视频。

这是我的代码

struct MediaPicker: UIViewControllerRepresentable {
@Binding var video: URL?
    
typealias UIViewControllerType = PHPickerViewController

class Coordinator: NSObject, PHPickerViewControllerDelegate {
    
    var parent: MediaPicker
    
    init(_ parent: MediaPicker) {
        self.parent = parent
    }
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
                    
        if results.isEmpty {
            picker.dismiss(animated: true)
            return
        }
        let provider = results.first!.itemProvider
        
        if provider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
            provider.loadItem(forTypeIdentifier: UTType.movie.identifier) { url, err in
                if err != nil {return}
                if let url = url {
                    DispatchQueue.main.sync {
                        self.parent.video = url as! URL?
                        picker.dismiss(animated: true)
                    }
                }
            }
        }
    }
}

func makeUIViewController(context: Context) -> PHPickerViewController {
    var configuration = PHPickerConfiguration()
    configuration.preferredAssetRepresentationMode = .automatic
    let picker = PHPickerViewController(configuration: configuration)
    picker.delegate = context.coordinator
    return picker
}

func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
    
}

func makeCoordinator() -> Coordinator {
    return MediaPicker.Coordinator(self)
}
}

AVPlayer

swift swiftui uiview uikit phpicker
1个回答
0
投票

首先请设置

preferredAssetRepresentationMode = .current
- 选择视频后它将删除解码(对我来说,每个视频需要几秒钟的时间来解码 - 不可接受)。

其次,您需要将文件复制到临时文件夹,因为关闭后,所选文件将被删除,您将无法使用它。来自文档

此方法将文件数据的副本写入临时文件,系统在完成处理程序返回时删除该文件。

看看我为案例编写的带有视频的代码:

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    itemProviders = results.map(\.itemProvider)
    
    itemProviders.forEach {
        guard let typeIdentifier = $0.registeredTypeIdentifiers.first,
              let utType = UTType(typeIdentifier) else { return }
         if utType.conforms(to: .movie) {
            var videoName = ""
            if let suggestedName = $0.suggestedName {
                if utType.conforms(to: .mpeg4Movie) {
                    videoName = suggestedName + ".mp4"
                } else {
                    videoName = suggestedName + ".mov"
                }
            }
            let group = DispatchGroup()
            group.enter()
            $0.loadFileRepresentation(forTypeIdentifier: typeIdentifier) { [weak self] url, error in
                guard let self, let url else { return }
                if let error {
                    print(error.localizedDescription)
                }
                // copying file
                let fm = FileManager.default
                let destination = fm.temporaryDirectory.appendingPathComponent(videoName)
                do {
                    try fm.copyItem(at: url, to: destination)
                } catch {
                    print(error.localizedDescription)
                }
    
                group.leave()
                group.notify(queue: DispatchQueue.global()) {
                    // do staff with video
                    self.output.videoIsPicked(url: destination)
                }
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.