我正在尝试构建一个小玩具iOS应用,它可以合并用户照片库中的两个视频资源。我已经达到了使用AVMutableComposition
实例合并视频的程度,现在我需要导出合成。我正在使用以下代码:
func saveEditedComposition(_ composition: AVMutableComposition) {
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let savePath = (documentDirectory as NSString).strings(byAppendingPaths: ["mergeVideo.mov"])[0]
let url = NSURL(fileURLWithPath: savePath)
// Set up exporter
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else { return }
exporter.outputURL = url as URL
exporter.outputFileType = AVFileTypeQuickTimeMovie
exporter.shouldOptimizeForNetworkUse = true
// Perform the export
exporter.exportAsynchronously(completionHandler: { () -> Void in
// Upon completion of the export,
DispatchQueue.global().async {
if exporter.status == .completed {
let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [exporter.outputURL!], options: nil))
let phAsset = fetchResult.firstObject! // Crashes here, returning nil.
}
}
})
}
问题是,当运行completionHandler时,我能够看到我的导出器已完成且没有错误(if exporter.status == .completed {
),但是当我尝试访问exporter.outputURL
处的资产时,它返回空PHFetchResult<PHAsset>
。谁能看到我在这里做错了什么?
答案 0 :(得分:1)
您正在将视频导出到文件系统(Documents目录),然后从相机胶卷/ ALAssetsLibrary
中提取。
这取决于您对导出文件的操作。如果它需要在ALAssetsLibrary
中,您可以使用
ALAssetsLibrary().writeVideoAtPath(toSavedPhotosAlbum: exporter.outputURL!) { alAssetURL, error in
}
但是,ALAssetsLibrary
现已弃用,您应该使用PHPhotoLibrary
。我不知道照片框架,但我认为它的工作原理如下:
var placeHolder: PHObjectPlaceholder?
PHPhotoLibrary.shared().performChanges({
let changeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: exporter.outputURL!)
if let changeRequest = changeRequest {
// maybe set date, location & favouriteness here?
placeHolder = changeRequest.placeholderForCreatedAsset
}
}) { success, error in
placeHolder?.localIdentifier // should identify asset from now on?
}
如果您不需要视频存放在相机胶卷中,那么您可以直接使用exporter.outputURL!
中的文件。