0

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

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

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

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

ответ

0

Итак, я искал, пытаясь выяснить, что могло бы вызвать это, и выясняется, что это было вызвано тем, что скрытые свойства слоев установлены в YES. Установив его в НЕТ, появляются все слои, но они никогда не уходили. Поэтому мне пришлось изменить свойство autoreverses анимации на 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]; 
}