0

I'm trying to do an additive animation on a AVPlayerLayer's bounds. By simply setting additive to YES, it breaks the animation. I need to do it additive so that the width and height can be animated with different animation parameters. Animating the key paths bounds.size.width and bounds.size.height do not work either.

I can animate other CALayer classes fine with the below code, so I'm starting to wonder if AVPlayerLayer has a bug.

Here is the code:

AVPlayerLayer *vl; 

// ...


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    NSURL *path = [[NSBundle mainBundle] URLForResource:@"vid" withExtension:@"mp4"]];
    AVPlayer *player = [AVPlayer playerWithURL: path];
    vl = [AVPlayerLayer playerLayerWithPlayer:player];
    vl.videoGravity = AVLayerVideoGravityResize;
//     vl = [CALayer layer]; // a normal calayer animates properly

    vl.backgroundColor = [NSColor redColor].CGColor;
    vl.frame = CGRectMake(200,100,150,100);
    [_window.contentView.layer addSublayer:vl];
}

- (IBAction)animate:(id)sender {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
    animation.fromValue = [NSValue valueWithRect:CGRectMake(0,0,0, 0)];
    animation.toValue = [NSValue valueWithRect:CGRectMake(0,0,240, 60)];
    animation.duration = 4;
    animation.additive = YES;

    [vl addAnimation:animation forKey:nil];
}

This is what it looks like:

enter image description here

The red area should be the video playing.

You can check out the sample project I created here: https://www.dropbox.com/s/jxuh69wiqdwnuc6/PlayerLayer%20size%20Animation.zip?dl=1

Hooper
  • 195
  • 13

1 Answers1

0

The frame property of a CALayer is a derived property, dependent on the position, anchorPoint, bounds and transform of the layer. Instead of animating the frame, you should instead animate the position or bounds, depending on what effect you are trying to accomplish.

You may first take a look at this:

Q: When I try to animate the frame of a CALayer nothing happens. Why?

This can also help: How to animate the frame of an layer with CABasicAnimation?

And those code may be helpul to you:

NSURL *fileUrl = [NSURL fileURLWithPath:@"yourFilePath"];
AVPlayer *player = [[AVPlayer alloc] initWithURL:fileUrl];

CALayer *superlayer = self.view.layer;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
[superlayer addSublayer:playerLayer];

[player play];

playerLayer.videoGravity = AVLayerVideoGravityResize;
playerLayer.frame = CGRectMake(10, 200, 320, 200);
playerLayer.position = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);

CGRect startBounds = CGRectMake(10, 200, 200, 150);
CGRect endBounds = CGRectMake(10, 200, 320, 200);

CABasicAnimation * sizeAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];

sizeAnimation.fromValue = [NSValue valueWithRect:startBounds] ;
sizeAnimation.toValue = [NSValue valueWithRect:endBounds] ;
sizeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
sizeAnimation.duration = 4;

[playerLayer addAnimation:sizeAnimation forKey:@"bounds"];
Community
  • 1
  • 1
Stoull
  • 1,098
  • 8
  • 13
  • 1
    The code in the question _is_ animating bounds, not frame. The code example in the original question works for normal CALayers, so it seems to be a quirk specific to AVPlayerLayers – Hooper May 27 '16 at 11:58
  • The code example in the original question is animating bounds also! Because you can't animate the frame of a CALayer ! – Stoull May 28 '16 at 00:51