草庐IT

ios - 将 AVMutableVideoComposition 与 CIFilter 一起使用会忽略 AVVideoCompositionCoreAnimationTool animationTool 参数

coder 2024-01-29 原文

我正在尝试在 iOS 中创建一个视频组合,将 CIFilter 的应用程序和核心动画层的应用程序结合在一起。这两个操作都单独工作,但是尝试将它们组合在一起在一个过程中似乎行不通。

当使用 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" )
        }

似乎 videoComp.instructions[0] 是一个私有(private)的 AVCoreImageFilterVideoCompositionInstruction 类。替换它会产生异常,并且添加额外的指令会导致导出完成而实际上没有做任何事情。

这可能是我尝试做的事情是不可能的,实际上我必须对视频进行两次传递(一次用于 CIFilter,另一次用于 CALayers)。但是处理到一个临时输出文件,然后以 2 遍的方式再次重新处理它感觉不对。

有人知道如何让它工作吗?

谢谢,

最佳答案

1、你的代码是在模拟器上运行的吗? 它接缝动画层无法在模拟器上渲染到视频(层的背景可以)。

2、如果您自己创建一个AVVideoCompositionInstruction,请确保将enablePostProcessing设置为YES。

关于ios - 将 AVMutableVideoComposition 与 CIFilter 一起使用会忽略 AVVideoCompositionCoreAnimationTool animationTool 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44375157/

有关ios - 将 AVMutableVideoComposition 与 CIFilter 一起使用会忽略 AVVideoCompositionCoreAnimationTool animationTool 参数的更多相关文章

随机推荐