在iOS中将特定时间的文本添加到video

我正在创建一个基于video的应用程序,我必须从本地库中选择任何video,并且必须使用CATextLayer在video上添加文本。 为此我使用下面的代码:

- (void) createWatermark:(UIImage*)image video:(NSURL*)videoURL { if (videoURL == nil) return; AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoURL options:nil]; AVMutableComposition* mixComposition = [AVMutableComposition composition]; AVMutableCompositionTrack* compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; AVAssetTrack* clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil]; [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; // create the layer with the watermark image CALayer* aLayer = [CALayer layer]; aLayer.contents = (id)image.CGImage; aLayer.frame = CGRectMake(50, 100, image.size.width, image.size.height); aLayer.opacity = 0.9; //sorts the layer in proper order AVAssetTrack* videoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; CGSize videoSize = [videoTrack naturalSize]; 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:aLayer]; // create text Layer CATextLayer* titleLayer = [CATextLayer layer]; titleLayer.backgroundColor = [UIColor clearColor].CGColor; titleLayer.string = @"Dummy text"; titleLayer.font = CFBridgingRetain(@"Helvetica"); titleLayer.fontSize = 28; titleLayer.shadowOpacity = 0.5; titleLayer.alignmentMode = kCAAlignmentCenter; titleLayer.frame = CGRectMake(0, 50, videoSize.width, videoSize.height / 6); [parentLayer addSublayer:titleLayer]; //create the composition and add the instructions to insert the layer: AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition]; videoComp.renderSize = videoSize; videoComp.frameDuration = CMTimeMake(1, 30); videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; /// instruction AVMutableVideoCompositionInstruction* instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]); AVAssetTrack* mixVideoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:mixVideoTrack]; instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; videoComp.instructions = [NSArray arrayWithObject: instruction]; // export video _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality]; _assetExport.videoComposition = videoComp; NSLog (@"created exporter. supportedFileTypes: %@", _assetExport.supportedFileTypes); NSString* videoName = @"NewWatermarkedVideo.mov"; NSString* exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName]; NSURL* exportUrl = [NSURL fileURLWithPath:exportPath]; if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil]; _assetExport.outputFileType = AVFileTypeQuickTimeMovie; _assetExport.outputURL = exportUrl; _assetExport.shouldOptimizeForNetworkUse = YES; [_assetExport exportAsynchronouslyWithCompletionHandler: ^(void ) { //Final code here switch (_assetExport.status) { case AVAssetExportSessionStatusUnknown: NSLog(@"Unknown"); break; case AVAssetExportSessionStatusWaiting: NSLog(@"Waiting"); break; case AVAssetExportSessionStatusExporting: NSLog(@"Exporting"); break; case AVAssetExportSessionStatusCompleted: NSLog(@"Created new water mark image"); _playButton.hidden = NO; break; case AVAssetExportSessionStatusFailed: NSLog(@"Failed- %@", _assetExport.error); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Cancelled"); break; } } ]; } 

使用上面的代码,我可以在我的video上设置文本。 但是现在我必须在CATextLayer上给出FadeIN / Fade Out动画,或者在Video上显示移动文本。 请建议我。 提前致谢!

尝试使用核心动画框架中声明的CAKeyframeAnimation类。

例如:

 //start from zero opacity titleLayer.opacity = 0; CAKeyframeAnimation *fadeInAndOut = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; fadeInAndOut.duration = 5.0; //5 seconds will be your fade in fade out animation. fadeInAndOut.autoreverses = NO; // from 0.0 * animDuration time to 0.2 * animDuration time your animation will animate opacity from zero to 1.0. // from 0.2 * animDuration time to 0.8 * animDuration time your opacity will be 1.0 // from 0.8 * animDuration time to 1.0 * animDuration time your animation will animate opacity from 1.0 opacity to zero. fadeInAndOut.keyTimes = @[@(0.0), @(0.2), @(0.8), @(1.0)]; fadeInAndOut.values = @[@(0.0), @(1.0), @(1.0), @(0.0)]; fadeInAndOut.beginTime = 1.0; fadeInAndOut.removedOnCompletion = NO; fadeInAndOut.fillMode = kCAFillModeBoth; [titleLayer addAnimation:fadeInAndOut forKey:nil]; 

我希望你能清楚。 使用相同的方法,您可以设置标签位置的动画。

UPDATE

对于动画位置试试这个

 CAKeyframeAnimation *fadeInAndOut = [CAKeyframeAnimation animationWithKeyPath:@"position"]; fadeInAndOut.duration = 5.0; fadeInAndOut.autoreverses = NO; fadeInAndOut.keyTimes = @[@(0.0), @(0.2), @(0.8), @(1.0)]; fadeInAndOut.values = @[[NSValue valueWithCGPoint:CGPointMake(20, 40)], [NSValue valueWithCGPoint:CGPointMake(200, 40)], [NSValue valueWithCGPoint:CGPointMake(200, 40)], [NSValue valueWithCGPoint:CGPointMake(400, 40)]]; fadeInAndOut.beginTime = 1.0; fadeInAndOut.removedOnCompletion = NO; fadeInAndOut.fillMode = kCAFillModeBoth; [titleLayer addAnimation:fadeInAndOut forKey:nil]; 

为了解释目的,我硬编码了点。 你可以自己计算点数和动画持续时间。