I am working with image overlay for the watermark effect in a video using swift. I use AVFoundation for this, but somehow I fail.
Below is my code for overlay image / text
let path = NSBundle.mainBundle().pathForResource("sample_movie", ofType:"mp4") let fileURL = NSURL(fileURLWithPath: path!) let composition = AVMutableComposition() var vidAsset = AVURLAsset(URL: fileURL, options: nil) // get video track let vtrack = vidAsset.tracksWithMediaType(AVMediaTypeVideo) let videoTrack:AVAssetTrack = vtrack[0] as! AVAssetTrack let vid_duration = videoTrack.timeRange.duration let vid_timerange = CMTimeRangeMake(kCMTimeZero, vidAsset.duration) var error: NSError? let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) compositionvideoTrack.insertTimeRange(vid_timerange, ofTrack: videoTrack, atTime: kCMTimeZero, error: &error) compositionvideoTrack.preferredTransform = videoTrack.preferredTransform // Watermark Effect let size = videoTrack.naturalSize let imglogo = UIImage(named: "image.png") let imglayer = CALayer() imglayer.contents = imglogo?.CGImage imglayer.frame = CGRectMake(5, 5, 100, 100) imglayer.opacity = 0.6 // create text Layer let titleLayer = CATextLayer() titleLayer.backgroundColor = UIColor.whiteColor().CGColor titleLayer.string = "Dummy text" titleLayer.font = UIFont(name: "Helvetica", size: 28) titleLayer.shadowOpacity = 0.5 titleLayer.alignmentMode = kCAAlignmentCenter titleLayer.frame = CGRectMake(0, 50, size.width, size.height / 6) let videolayer = CALayer() videolayer.frame = CGRectMake(0, 0, size.width, size.height) let parentlayer = CALayer() parentlayer.frame = CGRectMake(0, 0, size.width, size.height) parentlayer.addSublayer(videolayer) parentlayer.addSublayer(imglayer) 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 = NSArray(object: layerinstruction) as [AnyObject] layercomposition.instructions = NSArray(object: instruction) as [AnyObject] // create new file to receive data let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) let docsDir: AnyObject = dirPaths[0] let movieFilePath = docsDir.stringByAppendingPathComponent("result.mov") let movieDestinationUrl = NSURL(fileURLWithPath: movieFilePath) // use AVAssetExportSession to export video let assetExport = AVAssetExportSession(asset: composition, presetName:AVAssetExportPresetHighestQuality) assetExport.outputFileType = AVFileTypeQuickTimeMovie assetExport.outputURL = movieDestinationUrl assetExport.exportAsynchronouslyWithCompletionHandler({ switch assetExport.status{ case AVAssetExportSessionStatus.Failed: println("failed \(assetExport.error)") case AVAssetExportSessionStatus.Cancelled: println("cancelled \(assetExport.error)") default: println("Movie complete") // play video NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in self.playVideo(movieDestinationUrl!) }) } })
By this code, I do not get an overlay .... I do not know what I'm doing wrong ...
Questions:
- Is there a missing thing in this code? Or any problem with this code?
- Does this code only work with recorded video or all videos, including video from the gallery?
source share