我試圖在iOS中同時組合一個CIFilter應用程序和一個核心動畫層。這兩種操作都是單獨運行的,但是試圖將它們組合在一起看起來並不奏效。與CIFilter一起使用AVMutableVideoComposition會忽略AVVideoCompositionCoreAnimationTool animationTool參數
當使用AVMutableVideoComposition(asset:applyCIFiltersWithHandler :)時,似乎animationTool參數被忽略。有沒有其他人經歷過這個?我已經看到一些人建議在AVMutableVideoComposition回調期間添加任何額外的CA層,但是我的CALayer中有一些動畫,所以我看不到它如何可靠地工作。
下面是我使用的代碼:
let clipVideoTrack = asset.tracks(withMediaType:AVMediaTypeVideo)[0]
let mixComposition = AVMutableComposition()
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let videoRange = CMTimeRangeMake(startTime ?? kCMTimeZero, CMTimeSubtract(stopTime ?? asset.duration, startTime ?? kCMTimeZero))
try compositionVideoTrack.insertTimeRange(videoRange, of: clipVideoTrack, at: kCMTimeZero)
let parentLayer = CALayer()
let videoLayer = CALayer()
let overlayLayer = CALayer()
let targetDimention: CGFloat = 900.0
let videoWidthDivisor = clipVideoTrack.naturalSize.width/targetDimention
let actualDimention = clipVideoTrack.naturalSize.width/videoWidthDivisor;
let targetVideoSize = CGSize(width: actualDimention, height: actualDimention)
parentLayer.frame = CGRect(x: 0, y: 0, width: targetVideoSize.width, height: targetVideoSize.height)
videoLayer.frame = CGRect(x: 0, y: 0, width: targetVideoSize.width, height: targetVideoSize.height)
overlayLayer.frame = CGRect(x: 0, y: 0, width: targetVideoSize.width, height: targetVideoSize.height)
parentLayer.addSublayer(videoLayer)
for annotation in mediaAnnotationContainerView.mediaAnnotationViews
{
let renderableLayer = annotation.renderableCALayer(targetSize: targetVideoSize)
parentLayer.addSublayer(renderableLayer)
}
let filter = CIFilter(name: "CISepiaTone")!
filter.setDefaults()
let videoComp = AVMutableVideoComposition(asset: asset, applyingCIFiltersWithHandler:
{ request in
let source = request.sourceImage.clampingToExtent()
filter.setValue(source, forKey: kCIInputImageKey)
let output = filter.outputImage!.cropping(to: request.sourceImage.extent)
request.finish(with: output, context: nil)
})
videoComp.renderSize = targetVideoSize
videoComp.frameDuration = CMTimeMake(1, 30)
videoComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
let url = AVAsset.tempMovieUrl
let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
exporter?.outputURL = url
exporter?.outputFileType = AVFileTypeMPEG4
exporter?.shouldOptimizeForNetworkUse = true
exporter?.videoComposition = videoComp
exporter?.exportAsynchronously
{
print("Export completed")
}
看來,videoComp.instructions [0]是一個私人AVCoreImageFilterVideoCompositionInstruction類。將其替換會產生一個異常,並且添加額外的指令會導致完成導出,而不會執行任何操作。
這可能是我試圖做的事情是不可能的,而且我實際上必須在視頻上做兩遍(一次是CIFilter,另一次是CALayers)。但是處理到一個臨時輸出文件,然後再以2遍方式重新處理,感覺不對。
有誰知道如何讓這個工作?
感謝,
雷