我正在通过使用AVFoundation和AVMutableComposition缩放单个视频来创建视频合成。当我应用除1之外的任何缩放(更大或更小)时,我得到最终结果的颜色偏移。无论用作源的视频还是用作目标的预设/格式(MOV / MP4,ProRes / H24 ......),我都会遇到此问题。
以下是相关代码,受到另一个StackOverflow问题(Swift Video Resizer AVAsset)的广泛启发
func resizer(inputURL: URL , completion: @escaping (URL?) -> Void ){
let videoAsset = AVAsset(url: inputURL) as AVAsset
let clipVideoTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo).first! as AVAssetTrack
let composition = AVMutableComposition()
composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = clipVideoTrack.naturalSize
videoComposition.frameDuration = CMTimeMake(1, 30)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(start: kCMTimeZero, duration: clipVideoTrack.asset!.duration)
let transformer : AVMutableVideoCompositionLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
// If anything that 1 on both, colors are shifted!
let transform = CGAffineTransform(scaleX: 1.001, y: 1.001)
transformer.setTransform(transform, at: kCMTimeZero)
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
// Export part, left for facility
let exporter = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
exporter.videoComposition = videoComposition
let outputURL = URL(fileURLWithPath: "/path/to/destination/video.mov")
exporter.outputURL = outputURL
exporter.outputFileType = AVFileTypeQuickTimeMovie
exporter.exportAsynchronously(completionHandler: { () -> Void in
completion(outputURL)
})
}
解决方案是在视频结束时重置转换:
// Add this line to fix the issue:
transformer.setTransform(CGAffineTransform.identity, at: kCMTimeZero + clipVideoTrack.asset!.duration)
// Before this lines:
instruction.layerInstructions = [transformer]
videoComposition.instructions = [instruction]
不确定原因,但如果您有多个曲目用于合成,也可以使用。