2014-02-10 3 views
5

비디오에 텍스트 오버레이를 추가하는 방법을 보여주는 몇 가지 예제를 발견했습니다. AVMutableVideoComposition을 사용한 텍스트 오버레이를 특정 timerange에 추가하십시오.

레이의 튜토리얼 - http://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos

이 SO 답변 - 나뿐만 아니라 참조 몇 가지 다른 사람들이 있었다 How can I add a watermark in a captured video on iOS

. 내 코드는 그 대답과 거의 같아 보입니다. 나는 텍스트 오버레이가 비디오의 시작 부분에서 2 ~ 2 초 동안 만 나타나게하기 위해 그것을 조정하려고 노력했습니다. 내가 어떻게 성취 할 수 있는지에 대한 도움이 필요 하신가요?

여기 내 코드입니다. 이 작업은 오버레이가 전체 기간 동안 표시되도록 비디오를 내보내는 것과 같습니다.

if(vA) { 
    videoCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [videoCompositionTrack insertTimeRange:videoTimerange ofTrack:[[vA tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:&error]; 
    [videoCompositionTrack setPreferredTransform:[[[vA tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; 
    if(error) 
     NSLog(@"%@", error); 
} 

if(aA) { 
    audioCompositionTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    [audioCompositionTrack insertTimeRange:audioTimerange ofTrack:[[aA tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:&error]; 
    if(error) 
     NSLog(@"%@", error); 
} 

CGSize videoSize = [videoCompositionTrack naturalSize]; 

UIImage *myImage = [UIImage imageNamed:@"cover.png"]; 
CALayer *aLayer = [CALayer layer]; 
aLayer.contents = (id)myImage.CGImage; 
aLayer.frame = CGRectMake(5, 25, 100, 56); 
aLayer.opacity = 0.7; 

CATextLayer *titleLayer = [CATextLayer layer]; 
titleLayer.string = titleText; 
titleLayer.fontSize = 18; 
titleLayer.foregroundColor = titleColor.CGColor; 
titleLayer.alignmentMode = kCAAlignmentCenter; 
titleLayer.frame = CGRectMake(20, 10, videoSize.width - 40, 20); 
[titleLayer displayIfNeeded]; 

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]; 
if(titleText && [titleText length] > 0) { 
    [parentLayer addSublayer:titleLayer]; 
} 

AVMutableVideoComposition *videoComp = [AVMutableVideoComposition videoComposition]; 
videoComp.renderSize = videoSize; 
videoComp.frameDuration = CMTimeMake(1, 30); 
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 

AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
[instruction setTimeRange:CMTimeRangeMake(kCMTimeZero, [mixComposition duration])]; 
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; 
videoComp.instructions = [NSArray arrayWithObject:instruction]; 

AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality]; 
_assetExport.videoComposition = videoComp; 
_assetExport.outputFileType = AVFileTypeMPEG4; 
_assetExport.outputURL = outputFileUrl; 

[_assetExport exportAsynchronouslyWithCompletionHandler:^{ 
    AVAssetExportSessionStatus status = [_assetExport status]; 
    switch (status) { 
     case AVAssetExportSessionStatusFailed: 
      NSLog(@"Export Failed"); 
      NSLog(@"Export Error: %@", [_assetExport.error localizedDescription]); 
      NSLog(@"Export Error Reason: %@", [_assetExport.error localizedFailureReason]); 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"Export Completed"); 
      [self performSelectorOnMainThread:@selector(updateProgressIndicator:) withObject:[NSNumber numberWithFloat:2] waitUntilDone:YES]; 
      break; 
     case AVAssetExportSessionStatusUnknown: 
      NSLog(@"Export Unknown"); 
      break; 
     case AVAssetExportSessionStatusExporting: 
      NSLog(@"Export Exporting"); 
      break; 
     case AVAssetExportSessionStatusWaiting: 
      NSLog(@"Export Waiting"); 
      break; 
    } 
}]; 

답변

6

나는 내가해야 할 것을 알아 냈습니다. 정말 특별한 것은 아니 었습니다. 가능한 모든 것을 더 잘 이해할 필요가있었습니다.

기본적으로 내가해야 할 일은 텍스트가있는 레이어에 기본 불투명도 애니메이션을 추가하는 것입니다.

// My original code for creating the text layer 
CATextLayer *titleLayer = [CATextLayer layer]; 
. 
. 
. 
[titleLayer displayIfNeeded]; 

// the code for the opacity animation which then removes the text 
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
[animation setDuration:0]; 
[animation setFromValue:[NSNumber numberWithFloat:1.0]]; 
[animation setToValue:[NSNumber numberWithFloat:0.0]]; 
[animation setBeginTime:1]; 
[animation setRemovedOnCompletion:NO]; 
[animation setFillMode:kCAFillModeForwards]; 
[titleLayer addAnimation:animation forKey:@"animateOpacity"]; 
+0

titleLayer에 직접 알파 값을 설정할 수 없습니까? 왜 CABasicAnimation을 사용해야합니까? – Crashalot

+1

@scott F 특정 시간 범위를 제공하는 방법은 무엇입니까? –

+0

@PayalManiyar, 애니메이션 beginTime 및 duration을 설정하여 –