AVAssetExportSession 无法导出从 iCloud 下载的视频

Cih*_*Tek 6 avfoundation ios swift photosframework

我正在尝试创建从用户相册中选择的视频的缩小版本。输出的最大尺寸为 720p。因此,在检索视频时,我使用.mediumQualityFormatdeliveryMode。如果用户设备中不存在原始视频或其中等质量版本,这会导致 iOS 从 iCloud 检索 720p 视频。

\n
let videoRequestOptions = PHVideoRequestOptions()\nvideoRequestOptions.deliveryMode = .mediumQualityFormat\nvideoRequestOptions.isNetworkAccessAllowed = true\n\nPHImageManager.default().requestAVAsset(forVideo: asset, options: videoRequestOptions) { (asset, audioMix, info) in\n    // Proceess the asset\n}\n
Run Code Online (Sandbox Code Playgroud)\n

问题是,当我用来AVAssetExportSession创建资产的缩小版本时,如果资产是中等变体而不是原始版本,则导出过程会立即失败并出现以下错误:

\n
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-17507), NSLocalizedDescription=\xc4\xb0\xc5\x9flem tamamlanamad\xc4\xb1, NSUnderlyingError=0x283bbcf60 {Error Domain=NSOSStatusErrorDomain Code=-17507 "(null)"}}\n
Run Code Online (Sandbox Code Playgroud)\n

我在任何地方都找不到有关此错误含义的任何内容。

\n

当我将deliveryMode属性设置为.auto或时.highQualityFormat,一切正常。

\n

当我检查资产 URL 时,我注意到从 iCloud 检索视频时,其文件名有一个“.medium”后缀,如下例所示:

\n

file:///var/mobile/Media/PhotoData/Metadata/PhotoData/CPLAssets/group338/191B2348-5E19-4A8E-B15C-A843F9F7B5A3.medium.MP4

\n

奇怪的是,如果我将FileManager这个 url 中的视频复制到另一个目录,AVAsset从该文件创建一个新文件,并在创建AVExportSession实例时使用该资源,问题就会消失。

\n

如果有人能够提供有关问题所在的一些见解,我将非常感激。

\n

这就是我用来AVAssetExportSession创建原始视频的缩小版本的方法。

\n
let originalVideoURL = // The url of the asset retrieved from requestAVAsset\n\nlet outputVideoPath = NSTemporaryDirectory() + "encodedVideo.mp4"\nlet outputVideoURL = URL(fileURLWithPath: outputVideoPath)\n\nguard\n        let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality),\n        let videoTrack = asset.tracks(withMediaType: .video).first else {\n        // Error handling\n    return\n}\n\nlet videoComposition = AVMutableVideoComposition()\nvideoComposition.renderSize = scaledSize // How this is calculated is irrelevant\nvideoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)\n\nlet layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)\nlet transform = videoTrack.preferredTransform\n\nlayerInstruction.setTransform(transform, at: .zero)\n\nlet instruction = AVMutableVideoCompositionInstruction()\ninstruction.timeRange = CMTimeRangeMake(start: .zero, duration: asset.duration)\ninstruction.layerInstructions = [layerInstruction]\nvideoComposition.instructions = [instruction]\n\nexportSession.videoComposition = videoComposition\nexportSession.outputURL = outputVideoURL\nexportSession.outputFileType = .mp4\nexportSession.shouldOptimizeForNetworkUse = true\n\nexportSession.exportAsynchronously(completionHandler: {[weak self] in\n    guard let self = self else { return }\n\n    if let url = exportSession.outputURL, exportSession.status == .completed {\n        // Works for local videos\n    } else {\n        // Fails with error code 17507 when loading videos with delivery size "Medium"\n    }\n})\n
Run Code Online (Sandbox Code Playgroud)\n