ich meinen Fehler gefunden. So ändern Sie können die Metadaten eines PHAsset
mit dem MediaType
MediaType.video
Sie das folgende Snippet verwenden, wo self
ist die PHAsset
:
Zuerst eine PHContentEditingOutput
erstellen müssen, können Sie das tun, mit einer PHContentEditingInput
von der Aufforderung an die PHAsset
Sie ändern möchten . Wenn Sie einen PHAsset
ändern, müssen Sie auch den .adjustmentData
Wert des PHContentEditingOutput
setzen oder der .performChanges()
Block wird fehlschlagen. wenn Sie
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)
}
})
}
Betrachten, dass:
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))")
}
})
}
})
}
})
Mit dem Snippet oben, Sie ändern Snippet die PHAsset
nach dem PHContentEditingOutput
in der folgenden Modifizieren Sie werden sehen, wie die Metadaten für einen User-Rating festlegen Entfernen Sie nicht die AVMetadataItem
mit dem gleichen Bezeichner wie den, den Sie hinzufügen möchten, der AVAssetExportSession
wird mehrere Elemente mit demselben Bezeichner für die AVAsset
festlegen.
HINWEIS:
Wenn Sie jetzt das Video durch die PHImageManager
zugreifen -Methode .requestAVAsset(forVideo:,options:,resultHandler:)
Sie haben eine PHVideoRequestOptions
-Objekt mit dem .version
Variable auf .current
zu übergeben. Es wird als Standardwert der Variablen festgelegt, aber wenn Sie es in .original
ändern, erhalten Sie das unveränderte Video von dieser Methode.