我正在开发一款为视频添加动态文字(如字幕)的应用。有许多类似的问题,但没有一个确实有一个可行的答案。我非常希望使用" ContentAnimate"而不是"内容"作为基于Synchronising image, text, and positioning with CoreAnimation的animationKeyPath 但这对我没用。
我可以将视频显示在视频上作为叠加层,但动画不起作用 - 我总是看到CATextLayer的原始基础文本。以下是我设置字幕和叠加的方法:
// 1 - Set up the text layer
CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
[subtitle1Text setFont:@"Helvetica-Bold"];
//[subtitle1Text setString:[NSString stringWithFormat:@"%@: %@", bookmark.creatorMonkeyName, bookmark.info]];
[subtitle1Text setString:@"Place holder"];
[subtitle1Text setFontSize:36];
[subtitle1Text setFrame:CGRectMake(0, 0, videoSize.width, 100)];
[subtitle1Text setAlignmentMode:kCAAlignmentCenter];
[subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]];
// 2 - The overlay
CALayer *overlayLayer = [CALayer layer];
[overlayLayer addSublayer:subtitle1Text];
overlayLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[overlayLayer setMasksToBounds:YES];
overlayLayer.hidden = YES;
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer];
videoComp.renderSize = videoSize;
videoComp.frameDuration = CMTimeMake(1, (int32_t) fps);
以下是我添加动画的方法:
CABasicAnimation *showCommentAnimation2 = [CABasicAnimation animationWithKeyPath:@"contents"];
[CATransaction begin];
[CATransaction setDisableActions:YES];
overlayLayer.hidden = NO;
showCommentAnimation2.fromValue = @"Hello";
showCommentAnimation2.toValue = @"Goodbye";
showCommentAnimation2.beginTime = bookmark.relativeTimeStamp;
showCommentAnimation2.duration = commentTimeDisplayed;
[subtitle1Text addAnimation:showCommentAnimation2 forKey:[@(i) stringValue]]; //"i" is an iterator, This should allow multiple animations of the same type
[CATransaction setDisableActions:NO];
[CATransaction commit];
字幕弹出并消失 - 但我总是得到文字"占位符"从来没有"你好"或者"再见"。
我使用以下方法将视频导出到相机胶卷:
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
_assetExport.videoComposition = videoComp;
_assetExport.outputFileType = @"public.mpeg-4";
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
if (AVAssetExportSessionStatusCompleted == _assetExport.status) {
DLog(@"AVAssetExportSessionStatusCompleted");
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
DLog(@"About to copy video to camera roll");
//move video to camera roll
[library writeVideoAtPathToSavedPhotosAlbum:outputFileUrl completionBlock:^(NSURL *assetURL, NSError *error) {
[self removeWaitingScreen];
dispatch_async(dispatch_get_main_queue(), ^(void){
MPMoviePlayerViewController* theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL: assetURL];
[_viewController presentMoviePlayerViewControllerAnimated:theMovie];
});
}];
} else{
// a failure may happen because of an event out of your control
// for example, an interruption like a phone call comming in
// make sure and handle this case appropriately
DLog(@"Error - Export Session Status: %ld", (long)_assetExport.status);
dispatch_async(dispatch_get_main_queue(), ^(void){
[self removeWaitingScreen];
[[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", NSStringFromClass([self class]))
message:NSLocalizedString(@"Video Creation Failed", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles: nil] autorelease] show];
});
}
[videoComp release];
}];
}];
有人可以帮忙吗?
如果有更好的方法将字幕刻录到视频中,我愿意接受建议。
感谢。
答案 0 :(得分:1)
具有关键路径contents
的动画无法与字符串值(@"Hello"
和@"Goodbye"
一起使用)。图层的contents
属性包含图像,手动设置或由图层本身绘制。
简单地设置文本图层的string
属性应足以导致隐式动画。但是,听起来你需要一个显式动画才能控制beginTime。这样做的方法是使用CATransition。有关示例,请参阅here。
答案 1 :(得分:0)
感谢jtbandes我明白了。
步骤1:创建一个动画,在适当的时间更改该图层的隐藏属性:
CAKeyframeAnimation *showCommentAnimation = [CAKeyframeAnimation animationWithKeyPath:@"hidden"];
[showCommentAnimation setValue:@"hidestring" forKey:@"MyAnimationType"];
showCommentAnimation.values = @[@(NO),@(YES)];
showCommentAnimation.keyTimes = @[@0.0, @1.0];
showCommentAnimation.calculationMode = kCAAnimationDiscrete;
showCommentAnimation.removedOnCompletion = NO;
showCommentAnimation.delegate = self;
第2步:为每个评论创建单独的CATextLayer
CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
将该图层的文本更改为相应的副标题:
[subtitle1Text setString:@"Actual subtitle for that layer"];
步骤3:使用适当的时间添加动画:
showCommentAnimation.beginTime = subtitle.relativeTimeStamp;
[subtitle1Text addAnimation:showCommentAnimation forKey:[@"setstring" stringByAppendingString:[@(i) stringValue]]]; //use showCommentAnimation to set hidden propert