2

I want to add an overlay image into a video. I use AVVideoComposition and CIFilter to do this, but AVAsynchronousCIImageFilteringRequest handler not called. I put some breakpoints (line debugPrint"Here", request.finish), but XCode doesn't hit the breakpoints. enter image description here

I got the video, but doesn't have the watermark.

func watermark(video asset: AVAsset, with image: UIImage, output outURL: URL) {
        guard let watermarkImage = CIImage(image: image) else {
            return
        }

        let context = CIContext(options: nil)

        let videoComposition = AVVideoComposition(asset: asset) { (request) in
            debugPrint("Here")
            let source = request.sourceImage.clampedToExtent()

            let watermarkFilter = CIFilter(name: "CISourceOverCompositing")

            watermarkFilter?.setValue(source, forKey: kCIInputBackgroundImageKey)

            let transform = CGAffineTransform(translationX: request.sourceImage.extent.width - watermarkImage.extent.width - 10, y: 10)
            watermarkFilter?.setValue(watermarkImage.transformed(by: transform), forKey: kCIInputImageKey)
            guard let outputImage = watermarkFilter?.outputImage else {
                return
            }

            request.finish(with: outputImage, context: context)
        }

        let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough)
        exporter?.outputFileType = .mov
        exporter?.outputURL = outURL
        exporter?.videoComposition = videoComposition
        exporter?.exportAsynchronously { [weak exporter] in
            guard let export = exporter else {
                return
            }

            switch export.status {
            case  .failed:
                print("failed \(exporter?.error)")
                break
            case .cancelled:
                print("cancelled \(exporter?.error)")
                break
            case .completed:
                print("complete")
            default:
                print("default")
            }
        }
    }
Thien Chu
  • 90
  • 7

2 Answers2

1

You shouldn't use passthrough preset with CI filtering. Try using another preset that defines a video format instead.

This docs doesn't mention CI filtering specifically but it states that using passthrough preset would lead to layer instructions being ignored. I would expect it is the same for CI filtering.

Important: If you export a video composition with an AVAssetExportSession object and specify the AVAssetExportPresetPassthrough export preset to let all tracks pass through, the transform defined in the video composition instruction (AVMutableVideoCompositionLayerInstruction) will not be applied. You must change the export preset to one that defines a video format (AVAssetExportPresetMediumQuality, for example) for the transform to be applied.

Thanh Pham
  • 2,021
  • 21
  • 30
  • Thanks for your help. I changed the preset, and now it works. – Thien Chu Jun 26 '18 at 07:27
  • Hey Thanh, I've posted question regards this subject. Any chance you can take a look and maybe help me and my team? We are stuck on a small issue for days ah : https://stackoverflow.com/questions/51114201/updating-avplayeritem-video-composition – Roi Mulia Jun 30 '18 at 10:53
0

With some help, I figured out, I used preset AVAssetExportPresetPassthrough, AVAssetExportSession ignore the filter. I changed the preset, now it works.

Thien Chu
  • 90
  • 7