2017-06-05 2 views
1

CIFilterのアプリケーションとCore Animation Layerの両方を組み合わせたiOSでビデオコンポジションを作成しようとしています。これらの操作はどちらも個別に機能しますが、1回のパスでそれらを結合しようとしても機能しません。CIFilterでAVMutableVideoCompositionを使用するとAVVideoCompositionCoreAnimationToolが無視されます。animationToolパラメータ

AVMutableVideoComposition(asset:applyingCIFiltersWithHandler :)を使用すると、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") 
     } 

[0]プライベートAVCoreImageFilterVideoCompositionInstructionクラスですvideoComp.instructionsようです。これを置き換えると例外が作成され、追加の命令を追加すると、実際に何もせずにエクスポートが完了します。

私がやろうとしていることは不可能なことかもしれませんし、実際にはビデオ(CIFilterの場合は1つ、CALayersの場合はもう1つ)で2回通過する必要があります。しかし、一時的な出力ファイルを処理してから2パスの方法で再度処理することは正しいと感じません。

誰でもこれを動作させる方法を知っていますか?

おかげで、

レイ

答えて

0

1、あなたはシミュレータ上でコードを実行していますか? シームアニメーションレイヤーは、シミュレータ上のビデオ(レイヤーのバックグラウンド)にレンダリングできません。

2あなた自身でAVVideoCompositionInstructionを作成する場合は、enablePostProcessingをYESに設定してください。

関連する問題