Trouble exporting video with custom animated property on layer

I am trying to overlay an animated gif on a video. For various reason I chose to accomplish this by creating an animatable property on the layer containing the gif called "frameIndex". As frameIndex change from one value to the next the gif frame changes. When I add my animated gif layer to a AVSynchronizedLayer and sync it to a AVPlayerItem my gif animates perfectly with the playback of the video. All seems good. However, the problem occures when I try to export the video and the animated gif together. When I export it seems to be very random as to which frame the animation starts at and how many of the frames will actually show in the animation as well as for how long.


So here is the relevant code.


The animation is created like this (minus the details of keyTimes and values):

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"frameIndex"];
animation.calculationMode = kCAAnimationDiscrete;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
animation.repeatCount = INFINITY;


This is the layer containing the gif. 'frameIndex' is the property I am animating

@interface AnimatedGifLayer : CALayer
@property (nonatomic) NSUInteger frameIndex;
@end
@implementation AnimatedGifLayer

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if( [key isEqualToString:@"frameIndex"] ) {
        return YES;
    }
    return [super needsDisplayForKey:key];
}

- (void)display {
    NSUInteger frameIndex = self.presentationLayer.frameIndex;
    UIImage *img = [self.animatedImage imageCachedAtIndex:frameIndex];
    if( img ) {
        self.contents = (id)img.CGImage;
    }
}

During playback I can see that "display" is being called correctly with the correct "frameIndex" and everything works as expected.


For the export there is a whole bunch of stuff to set up the composition and then I'm adding the animation as such:

videoComposition.animationTool = 
              [AVVideoCompositionCoreAnimationTool 
                            videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer
                                                                                    inLayer:parentLayer];


I have used the export code to export other animated layers on to a video and it works fine there. It's only in this case that I am using a custom property to animate that it does not work.


During the export process it seems to be pretty random as to when "display" is called. My guess is that the AVVideoCompositionCoreAnimationTool is not actually using display to render the frame animations but I'm not sure what it is using.


As a side note, this does work if I animate the "contents" property directly however for various reasons I would much rather get this implementation working.


Thanks in advance to anyone that took the time to read through all of this and contemplate a solution.

  • I have the same problem. Did you find a solution?

Add a Comment

Replies

Have you solved this problem?