Payal Maniyar
Payal Maniyar

Reputation: 4402

How to add Text for some duration of video in iOS SDK

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

Answers (3)

mubin
mubin

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

Jan
Jan

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

arsenius
arsenius

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

Related Questions