I am work with image overlay for watermark effect in video using swift.I am using AVFoundation
for this but somehow I am not succeed.
Following 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 am not achieve overlay....I don't know what I am doing wrong...
Questions:
The code provided by @El Captain would work. It's only missing:
assetExport.videoComposition = layercomposition
You can add this right after the instantiation of the AVAssetExportSession
NOTE: The code originally provided would only export the video track but not the audio track. If you need the audio track you could add something like this after you configure the compositionvideoTrack:
let compositionAudioTrack:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
for audioTrack in audioTracks {
try! compositionAudioTrack.insertTimeRange(audioTrack.timeRange, ofTrack: audioTrack, atTime: kCMTimeZero)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With