Ios7 CAKeyframeAnimation在导出视频时不设置CATextLayer动画

Ios7 CAKeyframeAnimation在导出视频时不设置CATextLayer动画,ios7,core-animation,avfoundation,cakeyframeanimation,avassetexportsession,Ios7,Core Animation,Avfoundation,Cakeyframeanimation,Avassetexportsession,我有一个应用程序,我正试图把一个视频时间戳。为此,我使用AVFoundation和Core动画在视频层上放置CATextLayer。如果我将文本放入CATextLayer的string属性,则该字符串将正确显示在导出的视频中。如果我将动画添加到CATextLayer,则文本永远不会更改。我想我忽略了什么,但我能找到它是什么 提前感谢您的帮助 下面是一个代码示例 AVMutableComposition *composition = [AVMutableComposition compositio

我有一个应用程序,我正试图把一个视频时间戳。为此,我使用AVFoundation和Core动画在视频层上放置CATextLayer。如果我将文本放入CATextLayer的string属性,则该字符串将正确显示在导出的视频中。如果我将动画添加到CATextLayer,则文本永远不会更改。我想我忽略了什么,但我能找到它是什么

提前感谢您的帮助

下面是一个代码示例

AVMutableComposition *composition = [AVMutableComposition composition];

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);

AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];

AVMutableCompositionTrack *audioCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSDictionary *assetOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

AVAsset *asset = [[AVURLAsset alloc] initWithURL:myUrl options:assetOptions];

AVAssetTrack *audioAssetTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:audioAssetTrack atTime:kCMTimeZero error:nil];

AVAssetTrack *videoAssetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil];

videoComposition.renderSize = videoCompositionTrack.naturalSize;

AVMutableVideoCompositionInstruction *videoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration);

AVMutableVideoCompositionLayerInstruction *videoCompositionLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];
[videoCompositionLayerInstruction setOpacity:1.0f atTime:kCMTimeZero];
videoCompositionInstruction.layerInstructions = @[videoCompositionLayerInstruction];

videoComposition.instructions = @[videoCompositionInstruction];

CALayer *parentLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0.0f, 0.0f, videoComposition.renderSize.width, videoComposition.renderSize.height);

CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(0.0f, 0.0f, videoComposition.renderSize.width, videoComposition.renderSize.height);
[parentLayer addSublayer:videoLayer];

CATextLayer *textLayer = [CATextLayer layer];
textLayer.font = (__bridge CFTypeRef)([UIFont fontWithName:@"Helvetica Neue" size:45.0f]);
textLayer.fontSize = 45.0f;
textLayer.foregroundColor = [UIColor colorWithRed:1.0f green:1.0f blue:1.0f alpha:1.0f].CGColor;
textLayer.shadowColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f].CGColor;
textLayer.shadowOffset = CGSizeMake(0.0f, 0.0f);
textLayer.shadowOpacity = 1.0f;
textLayer.shadowRadius = 4.0f;
textLayer.alignmentMode = kCAAlignmentCenter;
textLayer.truncationMode = kCATruncationNone;

CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"string"];

// Step 8: Set the animation values to the object.
keyFrameAnimation.calculationMode = kCAAnimationLinear;
keyFrameAnimation.values = @[@"12:00:00", @"12:00:01", @"12:00:02", @"12:00:03",
                             @"12:00:04", @"12:00:05", @"12:00:06", @"12:00:07",
                             @"12:00:08", @"12:00:09"];
keyFrameAnimation.keyTimes = @[[NSNumber numberWithFloat:0.0f], [NSNumber numberWithFloat:0.1f],
                               [NSNumber numberWithFloat:0.2f], [NSNumber numberWithFloat:0.3f],
                               [NSNumber numberWithFloat:0.4f], [NSNumber numberWithFloat:0.5f],
                               [NSNumber numberWithFloat:0.6f], [NSNumber numberWithFloat:0.7f],
                               [NSNumber numberWithFloat:0.8f], [NSNumber numberWithFloat:0.9f]];
keyFrameAnimation.beginTime = AVCoreAnimationBeginTimeAtZero;
keyFrameAnimation.duration = CMTimeGetSeconds(composition.duration);
keyFrameAnimation.removedOnCompletion = YES;

[textLayer addAnimation:keyFrameAnimation forKey:@"string"];
textLayer.frame = CGRectMake(0.0f, 20.0f, videoComposition.renderSize.width, 55.0f);
[parentLayer addSublayer:textLayer];
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPreset1920x1080];
exportSession.videoComposition = videoComposition;
exportSession.audioMix = audioMix;
exportSession.outputFileType = [exportSession.supportedFileTypes objectAtIndex:0];
exportSession.outputURL = mySaveUrl;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
    self.delegate = nil;

    switch (exportSession.status) {
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"Export session cancelled.");
            break;
        case AVAssetExportSessionStatusCompleted:
            NSLog(@"Export session completed.");
            break;
        case AVAssetExportSessionStatusFailed:
            NSLog(@"Export session failed.");
            break;
        case AVAssetExportSessionStatusUnknown:
            NSLog(@"Export session unknown status.");
            break;
        case AVAssetExportSessionStatusWaiting:
            NSLog(@"Export session waiting.");
            break;
        default:
            break;
    }
    NSError *error = exportSession.error;
    if (error != nil) {
        NSLog(@"An error ocurred while exporting.  Error: %@: %@", error.localizedDescription, error.localizedFailureReason);
    }
}];

我与苹果的技术支持部门保持联系,并告诉我这是他的SDK中的一个bug。他们正试图解决这个问题

另外,我在apple bug reporter中打开了一个事件,如果你是apple开发者,我建议你打开一个新的,对这个事件施加更多压力


致以最良好的祝愿。

最后,我喜欢CATextLayer和动画的解决方案。这可能不是最好的解决方案,但至少效果很好

为了解决这个问题,我们应该将NSString传递给UIImage或CALayer,然后将所有这些图像(CGImage)放在NSMutableArray中,并在CAKeyAnimation中加载这个可变数组,并修改contents变量

 -(UIImage *)imageFromText:(NSString *)text
 {
UIGraphicsBeginImageContextWithOptions(sizeImageFromText,NO,0.0);//Better resolution (antialiasing)
//UIGraphicsBeginImageContext(sizeImageFromText); // iOS is < 4.0

[text drawInRect:aRectangleImageFromText withAttributes:attributesImageFromText];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;
}
设置CAKeyAnimation以修改图像内容(更改图像)

它工作得非常好,但在阵列中创建5000或6000个图像需要1或2秒,并且在导出视频时,它会因溢出错误而崩溃。这是框架中的另一个bug


正如你们所知,这是框架中的一个问题,这是一个解决方案,至少在apple修复CATextLayer和动画问题之前,我也将此解决方案提供给了apple。

感谢更新,我必须向所有感兴趣阅读本文的人道歉,因为我没有及时更新我的问题。我正在与苹果公司合作。你是对的,这是一个bug,他们正在努力修复它。他们告诉我尝试将我的动画包装到一个动画组中,看看是否有效。这对我来说不是,但其他人的运气可能比我好。看来这个bug仍然存在,你有更新吗?另外,你有关于这个bug的雷达号吗?你知道如何在创建视频时在两幅图像之间产生过渡效果吗。如果你知道这是怎么可能的,请帮助我。。
 [NSMutableArrayAux addObject:(__bridge id)[self imageFromText:@"Hello"].CGImage];
 CAKeyframeAnimation *overlay = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
 overlay.values = [[NSArray alloc] initWithArray:NSMutableArrayAux];