Reputation: 4402
I have video having duration 4:00. Now I want to add text in video file as per the frames of video. Say for example from 00:30 to 1:50 duration I want to add text "Welcome". Now from 3:00 to 4:00 duration of video I want to add text "Awesome". How to achieve this functionality. I have referred below tutorial. It adds text in whole video not for some duration of video. https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos
Any help will be appriciated.
I am adding lines of code for add text on whole video:
- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition size:(CGSize)size
{
// 1 - Set up the text layer
CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
[subtitle1Text setFont:@"Helvetica-Bold"];
[subtitle1Text setFontSize:36];
[subtitle1Text setFrame:CGRectMake(0, 0, size.width, 100)];
[subtitle1Text setString:_subTitle1.text];
[subtitle1Text setAlignmentMode:kCAAlignmentCenter];
[subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]];
// 2 - The usual overlay
CALayer *overlayLayer = [CALayer layer];
[overlayLayer addSublayer:subtitle1Text];
overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
[overlayLayer setMasksToBounds:YES];
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer];
composition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}
Upvotes: 7
Views: 2767
Reputation: 11
Use "opacity" KeyPath instead of "transform.scale"
swift example :
private func add(text: String, to layer: CALayer, videoSize: CGSize) {
let attributedText = NSAttributedString(
string: text,
attributes: [
.font: UIFont(name: "ArialRoundedMTBold", size: 60) as Any,
.foregroundColor: UIColor(named: "rw-green")!,
.strokeColor: UIColor.white,
.strokeWidth: -3])
let textLayer = CATextLayer()
textLayer.string = attributedText
textLayer.shouldRasterize = true
textLayer.rasterizationScale = UIScreen.main.scale
textLayer.backgroundColor = UIColor.clear.cgColor
textLayer.alignmentMode = .center
textLayer.frame = CGRect(
x: 0,
y: videoSize.height * 0.66,
width: videoSize.width,
height: 150)
textLayer.displayIfNeeded()
textLayer.opacity = 0
let startVisible = CABasicAnimation(keyPath: "opacity")
startVisible.duration = 0.1 // for appearing in duration
startVisible.repeatCount = 1
startVisible.fromValue = 0.0
startVisible.toValue = 1.0
startVisible.beginTime = AVCoreAnimationBeginTimeAtZero + 5 // overlay time range start second
startVisible.isRemovedOnCompletion = false
startVisible.fillMode = CAMediaTimingFillMode.forwards
textLayer.add(startVisible, forKey: "startAnimation")
let endVisible = CABasicAnimation(keyPath: "opacity")
endVisible.duration = 0.1 // for disappearing in duration
endVisible.repeatCount = 1
endVisible.fromValue = 1.0
endVisible.toValue = 0.0
endVisible.beginTime = 10.0 // overlay time range end second
endVisible.fillMode = CAMediaTimingFillMode.forwards
endVisible.isRemovedOnCompletion = false
textLayer.add(endVisible, forKey: "endAnimation")
layer.addSublayer(textLayer)
}
call function after initializing overlayLayer.
ex :
add(
text: "Happy Birthday,\n Mubin",
to: overlayLayer,
videoSize: videoSize)
Upvotes: 1
Reputation: 1130
Look at your linked website: https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos Just use 2 CATextLayer's as shown there. Set their texts.
Set the first ones beginTime
property to 30 seconds and its duration
property to 80 seconds. The 2nd with a beginTime
of 180 seconds and a duration
of 60 seconds.
The result will be exported as it is shown in a video player.
Upvotes: 0
Reputation: 13266
Edit Does this answer work for you? You will have to add multiple text layers, and use a CABasicAnimation to show/hide each at the appropriate time (using setBeginTime:
).
Original Answer
Basically, just maintain a reference to the CATextLayer
in this section of code, and use an NSTimer called every second to update your text:
// 1 - Set up the text layer
CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
self.textLayer = subtitle1Text; // ### Keep a reference to this object and update it in timerDidFire
...
- (void)viewDidLoad{
...
// Add a timer at some point. Don't forget to invalidate it later
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerDidFire) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
...
}
- (void)timerDidFire{
if (currentPlaybackPosition <= some_value){
[self.textLayer setText:@"Welcome"];
} else if (currentPlaybackPosition <= some_bigger_value){
[self.textLayer setText:@"Awesome"];
}
...
}
Upvotes: 0