2012-04-23 6 views
11

편집 : 가장 이상한 점은 전체 앱에서이 코드를 실행하면 모든 것이 작동하지만 항상 내 영화를 만드는 중이었던 것처럼 보입니다. 유닛 테스트가 있었고 그곳에서만 작동하지 않았다. 이유는 무엇인지 알아 내려고 노력 중입니다 ...단위 테스트에서 실행할 때 CATextLayer가 AVMutableComposition에 나타나지 않습니다.

AVMutableComposition을 사용하여 비디오 + 오디오 + 텍스트를 결합하여 새 비디오로 내보내려고합니다.

내 코드가 WWDC '10

에서 AVEditDemo을 기반으로

나는 CATextLayer에 보라색 배경 그래서 난이 영화에 수출 된 사실을 알 수 있습니다 추가하지만 텍스트가 표시되지 않습니다 ... I 다양한 글꼴, 위치, 색상 정의로 놀았지만 아무것도 도움이되지 않았습니다. 그래서 여기에 코드를 게시하고 누군가가 비슷한 것을 발견했을 때 내가 무엇을 놓쳤는지를 알기로 결정했습니다. 여기

코드 (self.audio 및 self.video이 AVURLAssets 있습니다)입니다 :

CMTime exportDuration = self.audio.duration; 

AVMutableComposition *composition = [[AVMutableComposition alloc] init]; 

AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
AVAssetTrack *videoTrack = [[self.video tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 

// add the video in loop until the audio ends 
CMTime currStartTime = kCMTimeZero; 
while (CMTimeCompare(currStartTime, exportDuration) < 0) { 
    CMTime timeRemaining = CMTimeSubtract(exportDuration, currStartTime); 
    CMTime currLoopDuration = self.video.duration; 

    if (CMTimeCompare(currLoopDuration, timeRemaining) > 0) { 
     currLoopDuration = timeRemaining; 
    } 
    CMTimeRange currLoopTimeRange = CMTimeRangeMake(kCMTimeZero, currLoopDuration); 

    [compositionVideoTrack insertTimeRange:currLoopTimeRange ofTrack:videoTrack 
            atTime:currStartTime error:nil]; 

    currStartTime = CMTimeAdd(currStartTime, currLoopDuration); 
} 

AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVAssetTrack *audioTrack = [self.audio.tracks objectAtIndex:0]; 
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, self.audio.duration) ofTrack:audioTrack atTime:kCMTimeZero error:nil]; 

AVMutableVideoComposition *videoComposition; 

// the text layer part - THIS IS THE PART THAT DOESN'T WORK WELL 
CALayer *animatedTitleLayer = [CALayer layer]; 
CATextLayer *titleLayer = [[CATextLayer alloc] init]; 
titleLayer.string = @"asdfasdf"; 
titleLayer.alignmentMode = kCAAlignmentCenter; 
titleLayer.bounds = CGRectMake(0, 0, self.video.naturalSize.width/2, self.video.naturalSize.height/2); 
titleLayer.opacity = 1.0; 
titleLayer.backgroundColor = [UIColor purpleColor].CGColor; 

[animatedTitleLayer addSublayer:titleLayer]; 
animatedTitleLayer.position = CGPointMake(self.video.naturalSize.width/2.0, self.video.naturalSize.height/2.0); 

// build a Core Animation tree that contains both the animated title and the video. 
CALayer *parentLayer = [CALayer layer]; 
CALayer *videoLayer = [CALayer layer]; 
parentLayer.frame = CGRectMake(0, 0, self.video.naturalSize.width, self.video.naturalSize.height); 
videoLayer.frame = CGRectMake(0, 0, self.video.naturalSize.width, self.video.naturalSize.height); 
[parentLayer addSublayer:videoLayer]; 
[parentLayer addSublayer:animatedTitleLayer]; 

videoComposition = [AVMutableVideoComposition videoComposition]; 
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, exportDuration); 
AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack]; 

passThroughInstruction.layerInstructions = [NSArray arrayWithObject:passThroughLayer]; 
videoComposition.instructions = [NSArray arrayWithObject:passThroughInstruction]; 

videoComposition.frameDuration = CMTimeMake(1, 30); 
videoComposition.renderSize = self.video.naturalSize; 

AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality]; 

exportSession.videoComposition = videoComposition; 
exportSession.outputURL = [NSURL fileURLWithPath:self.outputFilePath]; 
exportSession.outputFileType = AVFileTypeQuickTimeMovie; 

[exportSession exportAsynchronouslyWithCompletionHandler:^() { 
    // save the video ... 
}]; 
+0

나는 잘 모르겠다. 도움이 될 수있다 .http : //stackoverflow.com/questions/7205820/iphone-watermark-on-recorded-video –

+0

고마워, 나는 거의 같은 것을하고있다. 거기에 언급 된 것은 무엇입니까. 누군가 내 코드와 관련 답변의 중요한 차이점을 발견하면 나는 매우 감사 할 것입니다. – yonix

+0

글꼴 크기를 설정해 보셨습니까? –

답변

0

추가 조사가 필요하지만 AFAICT 지금 CATextLayer는 AVMutableVideoComposition 내부 단순히 논리 단위 테스트 내에서 작동하지 않습니다 이 기능은 일반 대상에서 테스트해야합니다.

1

다른 문맥에서 같은 문제가 발생했습니다. 필자의 경우 AVMutableComposition을 백그라운드 스레드로 옮겼다. 그 준비 부분을 주 대기열/스레드로 다시 이동 시키면 CATextlayers 오버레이가 제대로 작동합니다.

이것은 단위 테스트 컨텍스트에 정확하게 적용되지는 않지만, CATextLayer/AVFoundation은 실행중인 UIKit/AppKit의 일부 (실행중인 드로잉 컨텍스트 - 현재 화면입니까?)에 의존합니다. 컨텍스트는 우리가보고있는 실패를 설명 할 수 있습니다.

+0

안녕하세요, Adam은 'AVMutableCompositionTracks' (비디오를 병합하는 방법과 비슷합니다)를 사용하여 이미지와 비디오를 병합 할 수 있는지 알고 있습니까, 아니면 병합 된 비디오에 이미지를 통합하는 데'CALayers '가 필요합니까? 질문 : http://stackoverflow.com/questions/34937862/merge-videos-images-in-avmutablecomposition-using-avmutablecompositiontrack – Crashalot

1

저는 거의 모든 것이 훌륭하게 렌더링되었고 CALayer 및 CGImage로 설정된 콘텐츠로 이미지가 렌더링되었습니다. CGTextLayer 텍스트를 제외하고 배경색을 CGTextLayer로 설정하면 beginTime과 duration도 완벽하게 렌더링됩니다. 실제 텍스트는 나타나지 않습니다. 그게 전부 시뮬레이터에 있었고, 나는 전화로 그것을 실행했습니다 : 그리고 그것은 완벽했습니다.

결론 : 시뮬레이터는 멋진 비디오를 렌더링합니다 ... CATextLayer를 사용할 때까지.

0

내 문제는 contentsGravity = kCAGravityBottomLeft를 설정해야한다는 것이 었습니다. 그렇지 않으면 텍스트가 화면에서 벗어났습니다.