2017-06-05 68 views
1

我試圖在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遍方式重新處理,感覺不對。

有誰知道如何讓這個工作?

感謝,

回答

0

1,你運行你的模擬器上的代碼? 它在模擬器上接縫動畫層無法渲染到視頻(圖層的背景可以)。

2,如果您自己創建AVVideoCompositionInstruction,請確保將enablePostProcessing設置爲YES。