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パスの方法で再度処理することは正しいと感じません。
誰でもこれを動作させる方法を知っていますか?
おかげで、
レイ