Swift,加载画廊的无压缩视频

Swift, load video of the gallery without compression

当您向用户提供使用以前在 iPhone 的图库中注册的带有 UIImagePickerController 的视频的可能性时,无论原始分辨率如何,它都会被导入并压缩为 1280x720。是否可以使用 UIImagePickerController 获得原始质量的原始视频?

UIImagePickerController.InfoKey.mediaURL 返回的 url 似乎是压缩文件的临时 url,因此不能用于获取原始文件。

我能想到的解决该问题的两种方法。首先,有一个 UIImagePickerController 的 属性 叫做 videoExportPreset。您可以将 属性 设置为 AVAssetExportPresetPassthrough

videoExportPreset can be used to specify the transcoding quality for videos (via a AVAssetExportPreset* string). If the value is nil (the default) then the transcodeQuality is determined by videoQuality instead. Not valid if the source type is UIImagePickerControllerSourceTypeCamera.

记得做import AVFoundation


第二种方式是实现自己的选择器,即使用PHAsset.

示例:

 let fetchResult = PHAsset.fetchAssets(with: .video, options: nil)

 let videoRequestOptions = PHVideoRequestOptions()
 videoRequestOptions.version = .original

 fetchResult.enumerateObjects { (asset, index, _) in
     PHImageManager.default().requestAVAsset(forVideo: asset, options: videoRequestOptions) { (avAsset, audioMix, infoDic) in
         //----
     }
 }

您可以根据需要设置AVCaptureSession.Preset。

var session: AVCaptureSession?

func video(){

        // Don't trigger camera access for the background
    guard AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == .authorized else {
        return
    }

    do {
        // Prepare avcapture session
        session = AVCaptureSession()
        session?.sessionPreset = AVCaptureSession.Preset.high //medium or low

        // Hook upp device
        let device = AVCaptureDevice.default(for: AVMediaType.video)
        let input = try AVCaptureDeviceInput(device: device!)
        session?.addInput(input)

        // Setup capture layer

        guard session != nil else {
            return
        }

        let captureLayer = AVCaptureVideoPreviewLayer(session: session!)
        captureLayer.frame = bounds
        captureLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        cameraBackground.layer.addSublayer(captureLayer)

        self.captureLayer = captureLayer
    } catch {
        session = nil
    }
}