AVVideoCompositionCoreAnimationTool не добавляет все CALayers

Хорошо, это поставило меня в тупик. Я рад опубликовать другой код, если он вам нужен, но я думаю, что этого достаточно. Я не могу в жизни понять, почему что-то идет не так. Я добавляю CALayers, содержащие изображения, в композицию с помощью AVVideoCompositionCoreAnimationTool. Я создаю NSArray всех аннотаций (см. интерфейс ниже), которые я хочу добавить, а затем добавляю их в слой анимации с помощью перечислителя. Неважно, сколько, насколько я могу судить, аннотаций в массиве, в выводимое видео попадают только те, которые добавляются последним циклом. Может ли кто-нибудь заметить, что мне не хватает?

Вот интерфейс для аннотаций

@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

А вот и сообщение, создающее видеокомпозицию с анимацией.

- (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;
}

Я хочу подчеркнуть, что видео выводится правильно, и слои появляются в нужное время, просто не ВСЕ слои. Очень запутался и был бы очень признателен за вашу помощь.


person Ari Black    schedule 20.04.2015    source источник


Ответы (1)


Итак, я возился, пытаясь выяснить, что могло быть причиной этого, и оказалось, что это было вызвано тем, что для скрытого свойства слоев было установлено значение YES. При установке значения NO все слои появляются, но никогда не исчезают. Поэтому мне пришлось изменить свойство автореверса анимации на YES и вдвое сократить продолжительность.

Поэтому я изменил код на это:

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];
}
person Ari Black    schedule 21.04.2015