0

好吧,這一個讓我完成了難倒。如果你需要它,我很高興發佈其他代碼,但我認爲這足夠了。我不能爲了我的生活找出事情出錯的原因。我使用AVVideoCompositionCoreAnimationTool將包含圖像的CALayers添加到合成中。我創建了一個包含所有註釋的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引起的。通過將其設置爲NO,所有圖層都會出現,但它們永遠不會消失。所以我不得不將動畫的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]; 
}