3

There are a couple of solutions for this suggested here in SO, I have tried all of them, and none seems to be working for Swift.

I have captured a .mov using AVCaptureFileOutput, written it to file and would like to add a watermark using a CALayer (it does not matter, if it's an image or actual text).

This is the code I have so far: (This exports the video without any visible watermark)

        let fileURL = url

        let composition = AVMutableComposition()
        let vidAsset = AVURLAsset(URL: fileURL, options: nil)

        // get video track
        let vtrack =  vidAsset.tracksWithMediaType(AVMediaTypeVideo)
        let videoTrack:AVAssetTrack = vtrack[0] 
        let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration)

        let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())

        do {
            try compositionvideoTrack.insertTimeRange(vid_timerange, ofTrack: videoTrack, atTime: kCMTimeZero)
        } catch {
            print("No Video!")
        }

        compositionvideoTrack.preferredTransform = videoTrack.preferredTransform

        // Watermark Effect
        let size = videoTrack.naturalSize

        // create text Layer
        let titleLayer = CATextLayer()
        titleLayer.backgroundColor = UIColor.whiteColor().CGColor
        titleLayer.string = "Dummy text"
        titleLayer.font = UIFont.systemFontOfSize(100)
        titleLayer.shadowOpacity = 0.5
        titleLayer.alignmentMode = kCAAlignmentCenter
        titleLayer.frame = CGRectMake(0, 50, 200, 200)
        titleLayer.display()

        let videolayer = CALayer()
        videolayer.frame = CGRectMake(0, 0, 200, 200)
        let parentlayer = CALayer()
        parentlayer.frame = CGRectMake(0, 0, 200, 200)
        parentlayer.addSublayer(videolayer)
        parentlayer.addSublayer(titleLayer)

        let layercomposition = AVMutableVideoComposition()
        layercomposition.frameDuration = CMTimeMake(1, 30)
        layercomposition.renderSize = size
        layercomposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videolayer, inLayer: parentlayer)

        // instruction for watermark
        let instruction = AVMutableVideoCompositionInstruction()
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration)
        let videotrack = composition.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
        let layerinstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videotrack)
        instruction.layerInstructions = [layerinstruction]
        layercomposition.instructions = [instruction]

        //create somewhat random filename
        let randomNumber = Int(arc4random_uniform(UInt32(99999999)))
        let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true) as NSArray
        let directory = paths.objectAtIndex(0)
        let documentPath = directory.stringByAppendingPathComponent("finalvideoWaterMark\(randomNumber).mov")
        let outPutURL = NSURL(fileURLWithPath: documentPath)

        //export the video
        let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality)
        assetExport!.outputFileType = AVFileTypeQuickTimeMovie
        assetExport!.outputURL = outPutURL
        assetExport!.exportAsynchronouslyWithCompletionHandler({
            NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                print("exported with watermark")
                self.finalVideoURL = outPutURL
                self.videoPlayer.contentURL = outPutURL
                self.videoPlayer.prepareToPlay()
                self.videoPlayer.play()
            })
        })
rmaddy
  • 314,917
  • 42
  • 532
  • 579
schnabler
  • 687
  • 7
  • 23

0 Answers0