. PHAsset MediaType MediaType.video, , self - PHAsset:
PHContentEditingOutput, PHContentEditingInput PHAsset, . PHAsset .adjustmentData PHContentEditingOutput, .performChanges().
self.requestContentEditingInput(with: options, completionHandler: {
(contentEditingInput, _) -> Void in
if contentEditingInput != nil {
let adjustmentData = PHAdjustmentData(formatIdentifier: starRatingIdentifier, formatVersion: formatVersion, data: NSKeyedArchiver.archivedData(withRootObject: rating))
let contentEditingOutput = PHContentEditingOutput(contentEditingInput: contentEditingInput!)
contentEditingOutput.adjustmentData = adjustmentData
self.applyRatingToVideo(rating, contentEditingInput, contentEditingOutput, completion: {
output in
if output != nil {
PHPhotoLibrary.shared().performChanged({
let request = PHAssetChangeRequest(for: self)
request.contentEditingOutput = output
}, completionHandler: {
success, error in
if !success {
print("can't edit asset: \(String(describing: error))")
}
})
}
})
}
})
PHAsset PHContentEditingOutput , , :
private func applyRatingToVideo(_ rating: Int, input: PHContentEditingInput, output: PHContentEditingOutput, completion: @escaping (PHContentEditingOutput?) -> Void) {
guard let avAsset = input.audiovisualAsset else { return }
guard let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) else { return }
var mutableMetadata = exportSession.asset.metadata
let metadataCopy = mutableMetadata
for item in metadataCopy {
if item.identifier == AVMetadataIdentifierQuickTimeMetadataRatingUser {
mutableMetadata.remove(object: item)
}
}
let metadataItem = AVMutableMetadataItem()
metadataItem.identifier = AVMetadataIdentifierQuickTimeMetadataRatingUser
metadataItem.keySpace = AVMetadataKeySpaceQuickTimeMetadata
metadataItem.key = AVMetadataQuickTimeMetadataKeyRatingUser as NSString
metadataItem.value = NSNumber(floatLiteral: Double(rating))
exportSession.outputURL = output.renderedContentURL
mutableMetadata.append(metadataItem)
exportSession.metadata = mutableMetadata
exportSession.outputFileType = AVFileTypeQuickTimeMovie
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronously(completionHandler: {
if exportSession.status == .completed {
completion(output)
} else if exportSession.error != nil {
completion(nil)
}
})
}
, AVMetadataItem , , , AVAssetExportSession AVAsset.
:
PHImageManager -method .requestAVAsset(forVideo:,options:,resultHandler:), PHVideoRequestOptions -bject .version, .current. , .original, .