Skip to content

Instantly share code, notes, and snippets.

@kmdarshan
Created June 19, 2024 16:54
Show Gist options
  • Save kmdarshan/f45a9e807be2cabbaa3a2ed3e4a0d722 to your computer and use it in GitHub Desktop.
Save kmdarshan/f45a9e807be2cabbaa3a2ed3e4a0d722 to your computer and use it in GitHub Desktop.
import AVFoundation
func addWatermark(to videoURL: URL, watermark: UIImage) -> AVMutableComposition? {
// Create a new mutable composition
let mixComposition = AVMutableComposition()
// Add a new mutable track to the composition and get the first video track from the asset
guard let track = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)),
let asset = AVAsset(url: videoURL).tracks(withMediaType: .video).first else {
return nil
}
// Insert the video track into the mutable track at the start of the composition
do {
try track.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: asset, at: .zero)
} catch {
print("Error inserting time range: \(error)")
return nil
}
// Get the natural size of the video
let size = asset.naturalSize
// Create a new layer for the watermark and set its contents and frame
let watermarkLayer = CALayer()
watermarkLayer.contents = watermark.cgImage
watermarkLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
watermarkLayer.opacity = 0.5
// Create a new layer for the video and set its frame
let videoLayer = CALayer()
videoLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
// Create a new parent layer and add the video layer and watermark layer to it
let parentLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(watermarkLayer)
// Create a new mutable video composition and set its frame duration, render size, and animation tool
let videoComposition = AVMutableVideoComposition()
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
videoComposition.renderSize = size
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
// Create a new mutable video composition instruction and set its time range
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(start: .zero, duration: mixComposition.duration)
// Create a new mutable video composition layer instruction for the mutable track and set it as the layer instructions of the instruction
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
instruction.layerInstructions = [layerInstruction]
// Set the instruction as the instructions of the video composition
videoComposition.instructions = [instruction]
// Return the mutable composition
return mixComposition
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment