How to add water mark in recorded video at a proper position [ Top Middle ] in swift5

214 Views Asked by At

I tried a lot of code to add watermark (Image) in my recorded video but still unable to add. My video is in portrait mode.

Reference : https://stackoverflow.com/a/45304222

Issues :

  1. Video size got changed but water mark not visible to video.
  2. Video size got zero and blank but water mark not visible to video.
  3. I set video orientation then video got blank by 30 pixel from right but water mark not visible to video.

Code that I applied:

    func setWaterMarkVideoOutput(inputURL: URL) {
        //input file
        let asset = AVAsset.init(url: inputURL)
        let composition = AVMutableComposition.init()
        composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)

        //input clip
        let clipVideoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]

        //adding the image layer
        let imglogo = UIImage(named: "WatermarkImage")
        let watermarkLayer = CALayer()
        watermarkLayer.contents = imglogo?.cgImage
        watermarkLayer.frame = CGRect(x: 25, y: 25 ,width: 417, height: 103)
        watermarkLayer.opacity = 0.86

        let videoSize = clipVideoTrack.naturalSize
        let parentlayer = CALayer()
        let videoLayer = CALayer()

        parentlayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
        videoLayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
        parentlayer.addSublayer(videoLayer)
        parentlayer.addSublayer(watermarkLayer)


        //make it square
        let videoComposition = AVMutableVideoComposition()
        videoComposition.renderSize = CGSize(width: videoSize.width, height: videoSize.height)
        //change it as per your needs.
        videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
        videoComposition.renderScale = 1.0

        //Magic line for adding watermark to the video
        videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayers: [videoLayer], in: parentlayer)

        let instruction = AVMutableVideoCompositionInstruction()
        instruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: CMTimeMakeWithSeconds(60, preferredTimescale: 30))

        //rotate to potrait
        let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
        let t1 = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
        let t2: CGAffineTransform = t1.rotated(by: .pi/2)
        let finalTransform: CGAffineTransform = t2
        transformer.setTransform(finalTransform, at: CMTime.zero)
        instruction.layerInstructions = [transformer]
        videoComposition.instructions = [instruction]

        let documentsPath = NSTemporaryDirectory()
        let outputPath = "\(documentsPath)/\(String.uniqueFilename(withPrefix: "NewVideo")).mp4"
        let outputURL = URL(fileURLWithPath: outputPath)


        let exporter = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetMediumQuality)
        exporter?.outputFileType = AVFileType.mov
        exporter?.outputURL = outputURL
        exporter?.videoComposition = videoComposition

        exporter?.exportAsynchronously() {
            if exporter?.status == .completed {
                print("Export complete")
                DispatchQueue.main.async {
                    print("videoUrl:::", outputURL)
                }
                return
            } else if exporter?.status == .failed {
                print("Export failed - \(String(describing: exporter?.error))")
            }
            return
        }
    }

Please correct me what I did wrong in this method. Thank you in Advance.

0

There are 0 best solutions below