使用AVMutableVideoComposition后视频色彩失真,是否为色彩空间问题?
解决AVMutableComposition导出视频色彩褪色问题
问题核心
使用AVMutableComposition+AVVideoCompositionCoreAnimationTool结合CALayer渲染导出视频时,CoreAnimation默认色彩空间与视频色彩空间不匹配,导致色彩错误转换,出现视频偏亮、纯色层变色(如纯红变为偏橙红)的问题。
关键修复步骤
1. 为所有CALayer指定sRGB色彩空间
给宿主层、视频层、形状层统一设置色彩空间与缩放比例,强制CoreAnimation在sRGB空间内渲染:
// 宿主层 let parentLayer = CALayer() parentLayer.contentsScale = UIScreen.main.scale parentLayer.colorSpace = CGColorSpace(name: CGColorSpace.extendedSRGB) // 视频层(AVPlayerLayer) let videoLayer = AVPlayerLayer(player: nil) videoLayer.contentsScale = UIScreen.main.scale videoLayer.colorSpace = CGColorSpace(name: CGColorSpace.extendedSRGB) // 形状层 let shapeLayer = CAShapeLayer() shapeLayer.fillColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0).cgColor shapeLayer.contentsScale = UIScreen.main.scale shapeLayer.colorSpace = CGColorSpace(name: CGColorSpace.extendedSRGB)
2. 完善AVVideoComposition渲染配置
保留原有色彩空间参数的同时,匹配原视频的渲染尺寸与缩放比例:
let videoComposition = AVMutableVideoComposition() videoComposition.renderSize = originalVideoSize videoComposition.renderScale = UIScreen.main.scale videoComposition.colorPrimaries = AVVideoColorPrimaries_ITU_R_709_2 videoComposition.colorYCbCrMatrix = AVVideoYCbCrMatrix_ITU_R_709_2 videoComposition.colorTransferFunction = AVVideoTransferFunction_ITU_R_709_2
3. 修正AVAssetWriter输出配置
选用支持sRGB的像素格式,保持色彩空间参数与视频一致:
let videoOutputSettings: [String: Any] = [ AVVideoCodecKey: AVVideoCodecType.h264, AVVideoWidthKey: originalVideoSize.width, AVVideoHeightKey: originalVideoSize.height, AVVideoColorPropertiesKey: [ AVVideoColorPrimariesKey: AVVideoColorPrimaries_ITU_R_709_2, AVVideoTransferFunctionKey: AVVideoTransferFunction_ITU_R_709_2, AVVideoYCbCrMatrixKey: AVVideoYCbCrMatrix_ITU_R_709_2 ], AVVideoCompressionPropertiesKey: [ AVVideoAverageBitRateKey: 10_000_000, AVVideoMaxKeyFrameIntervalKey: 30 ] ]
原理说明
从单帧转换sRGB后色彩恢复正常的现象可以确定:CoreAnimation默认使用线性RGB色彩空间渲染,而视频采用ITU-R 709标准的YCbCr空间,两者间的转换未被正确处理。通过给所有CALayer指定sRGB色彩空间,强制CoreAnimation在sRGB空间完成渲染,再由AVFoundation正确转换到视频所需的YCbCr空间,即可解决色彩褪色问题。
直接导出原视频正常的结果,也验证了问题出在CoreAnimation渲染环节,而非AVAssetWriter本身。
内容的提问来源于stack exchange,提问作者tin
相关产品推荐
相关产品推荐

