AVVideoCompositionCoreAnimationTool不添加所有CALayers [英] AVVideoCompositionCoreAnimationTool not adding all CALayers

查看:106
本文介绍了AVVideoCompositionCoreAnimationTool不添加所有CALayers的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这个让我难过了.如果您需要,我很乐意发布其他代码,但我认为这已经足够.我无法为自己的生活弄清楚为什么出问题了.我正在使用AVVideoCompositionCoreAnimationTool将包含图像的CALayers添加到合成中.我创建了要添加的所有注释的NSArray(请参见下面的界面),然后使用枚举器将它们添加到动画层.就我所知,无论数组中有多少个批注,最终输出到视频中的唯一批注都是最后一个循环添加的批注.有人可以发现我所缺少的吗?

Okay, this one has me completed stumped. I'm happy to post other code if you need it but I think this is enough. I cannot for the life of me figure out why things are going wrong. I'm adding CALayers, which contain images, to a composition using AVVideoCompositionCoreAnimationTool. I create an NSArray of all the annotations (see interface below) I want to add and then add them to the animation layer with an enumerator. No matter how many, as far as I can tell, annotations are in the array, the only ones that end up in the outputted video are the ones added by the last loop. Can someone spot what I'm missing?

这是注释的界面

@interface Annotation : NSObject// <NSCoding>

@property float time;
@property AnnotationType type;
@property CALayer *startLayer;
@property CALayer *typeLayer;
@property CALayer *detailLayer;

+ (Annotation *)annotationAtTime:(float)time ofType:(AnnotationType)type;

- (NSString *)annotationString;

@end

这是创建带有动画的视频作品的消息.

And here's the message that creates the video composition with the animation.

- (AVMutableVideoComposition *)createCompositionForMovie:(AVAsset *)movie fromAnnotations:(NSArray *)annotations {
 AVMutableVideoComposition *videoComposition = nil;

if (annotations){
//CALayer *imageLayer = [self layerOfImageNamed:@"Ring.png"];
//imageLayer.opacity = 0.0;
//[imageLayer setMasksToBounds:YES];

Annotation *ann;
NSEnumerator *enumerator = [annotations objectEnumerator];

CALayer *animationLayer = [CALayer layer];
animationLayer.frame = CGRectMake(0, 0, movie.naturalSize.width, movie.naturalSize.height);

CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(0, 0, movie.naturalSize.width, movie.naturalSize.height);

[animationLayer addSublayer:videoLayer];

// TODO: Consider amalgamating this message and scaleVideoTrackTime:fromAnnotations
// Single loop instead of two and sharing of othe offset variables

while (ann = (Annotation *)[enumerator nextObject]) {
  CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
  animation.duration = 3; // TODO: Three seconds is the currently hard-coded display length for an annotation, should this be a configurable option after the demo?
  animation.repeatCount = 0;
  animation.autoreverses = NO;
  animation.removedOnCompletion = NO;
  animation.fromValue = [NSNumber numberWithFloat:1.0];
  animation.toValue = [NSNumber numberWithFloat:1.0];
  animation.beginTime = time;
  //  animation.beginTime = AVCoreAnimationBeginTimeAtZero;

  ann.startLayer.opacity = 0.0;
  ann.startLayer.masksToBounds = YES;
  [ann.startLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.startLayer];

  ann.typeLayer.opacity = 0.0;
  ann.typeLayer.masksToBounds = YES;
  [ann.typeLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.typeLayer];

  ann.detailLayer.opacity = 0.0;
  ann.detailLayer.masksToBounds = YES;
  [ann.detailLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.detailLayer];

}

  videoComposition = [AVMutableVideoComposition videoCompositionWithPropertiesOfAsset:movie];

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

  return videoComposition;
}

我想强调视频输出正确,并且确实在正确的时间显示了图层,而不是所有图层.非常困惑,非常感谢您的帮助.

I want to stress that the video outputs correctly and I do get the layers appearing at the right time, just not ALL the layers. Very confused and would greatly appreciate your help.

推荐答案

因此,我在四处摸索,试图找出可能导致此问题的原因,事实证明,这是由于图层的hidden属性设置为YES所致.通过将其设置为NO,将显示所有图层,但随后它们永不消失.因此,我不得不将动画的autoreverses属性更改为YES,并将持续时间减半.

So I was fiddling around trying to figure out what might have caused this and it turns out that it was caused by the layers hidden property being set to YES. By setting it to NO, all the layers appear but then they never went away. So I had to change the animation's autoreverses property to YES and halve the duration.

所以我将代码更改为此:

So I changed the code to this:

while (ann = (Annotation *)[enumerator nextObject]){
  CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
  animation.duration = 1.5; // TODO: Three seconds is the currently hard-coded display length for an annotation, should this be a configurable option after the demo?
  animation.repeatCount = 0;
  animation.autoreverses = YES; // This causes the animation to run forwards then backwards, thus doubling the duration, that's why a 3-second period is using 1.5 as duration
  animation.removedOnCompletion = NO;
  animation.fromValue = [NSNumber numberWithFloat:1.0];
  animation.toValue = [NSNumber numberWithFloat:1.0];
  animation.beginTime = time;
  //  animation.beginTime = AVCoreAnimationBeginTimeAtZero;

  ann.startLayer.hidden = NO;
  ann.startLayer.opacity = 0.0;
  ann.startLayer.masksToBounds = YES;
  [ann.startLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.startLayer];

  ann.typeLayer.hidden = NO;
  ann.typeLayer.opacity = 0.0;
  ann.typeLayer.masksToBounds = YES;
  [ann.typeLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.typeLayer];

  ann.detailLayer.hidden = NO;
  ann.detailLayer.opacity = 0.0;
  ann.detailLayer.masksToBounds = YES;
  [ann.detailLayer addAnimation:animation forKey:@"animateOpacity"];
  [animationLayer addSublayer:ann.detailLayer];
}

这篇关于AVVideoCompositionCoreAnimationTool不添加所有CALayers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆