Skip to content

Instantly share code, notes, and snippets.

@Starmel
Created March 13, 2019 11:51
Show Gist options
  • Save Starmel/1aa0183e37f6ad258b773bf7fad8d6ae to your computer and use it in GitHub Desktop.
Save Starmel/1aa0183e37f6ad258b773bf7fad8d6ae to your computer and use it in GitHub Desktop.
ios video text animation example
// STEP 1 - load resources
let asset = AVURLAsset(url: videoURL, options: nil)
let track = asset.tracks(withMediaType: AVMediaType.video)
let videoTrack = track[0] as AVAssetTrack
// STEP 2 - Prepare new layers to video.
let size = videoTrack.naturalSize
let videoLayer = CALayer()
videoLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
let textPosition = CGPoint(x: 230, y: 100)
let text = NSString(string: "1234567890")
let fontSize: CGFloat = 27.0
let textSize = text.size(withAttributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)])
let textLayer = CATextLayer()
textLayer.string = text
textLayer.fontSize = fontSize
textLayer.foregroundColor = UIColor.red.cgColor
textLayer.position = textPosition
textLayer.frame = CGRect(origin: textPosition, size: textSize)
textLayer.display()
let colorKeyframeAnimation = CABasicAnimation(keyPath: #keyPath(CATextLayer.opacity))
colorKeyframeAnimation.fromValue = 0
colorKeyframeAnimation.toValue = 1
colorKeyframeAnimation.duration = asset.duration.seconds
colorKeyframeAnimation.beginTime = AVCoreAnimationBeginTimeAtZero
colorKeyframeAnimation.isRemovedOnCompletion = false
textLayer.add(colorKeyframeAnimation, forKey: nil)
// STEP 3 - Put created layers in one.
let parentLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
parentLayer.addSublayer(videoLayer)
parentLayer.addSublayer(textLayer)
// STEP 4 - Compose layers
let videoComposition = AVMutableVideoComposition(propertiesOf: asset)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer,
in: parentLayer)
// STEP 5 - Render and export file.
let outputURL = tempFilePath()
let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)!
exporter.videoComposition = videoComposition
exporter.outputURL = outputURL
exporter.outputFileType = .mp4
exporter.exportAsynchronously {
DispatchQueue.main.async(execute: {
if (exporter.status == .completed) {
// outputURL
} else {
throw exporter.error
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment