2012-04-23 5 views
11

EDIT: Самое странное: кажется, что при запуске этого кода из полного приложения все работает, но я всегда запускал создание фильма из моего модульные тесты, и только там он не работал. Попытка выяснить, почему это так ...CATextLayer не отображается в AVMutableComposition при запуске из единичного теста

Я пытаюсь объединить видео + аудио + текст с помощью AVMutableComposition и экспортировать его на новое видео.

Мой код основан на AVEditDemo из WWDC '10

Я добавил фиолетовый фон с CATextLayer, так что я могу знать, за то, что экспортируется в кино, но текст не отображается ... Я попробовал играть с различными шрифтами, положением, определениями цвета, но ничего не помогло, поэтому я решил опубликовать здесь код и посмотреть, не наткнулся ли кто-нибудь на что-то подобное и может сказать, чего я не вижу.

Вот код (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 к фоновому потоку. Перемещение этой части подготовки обратно в основную очередь/нить сделало наложения CATextLayer снова правильными.

Это, скорее всего, не относится к контексту тестирования устройства, но я предполагаю, что CATextLayer/AVFoundation зависит от того, какая часть UIKit/AppKit работает/доступна (контекст рисования? Текущий экран?) В этом потоке контекст, который может объяснить неудачу, которую мы оба видим.

+0

Привет, Адам, вы знаете, можно ли объединять изображения и видео с помощью 'AVMutableCompositionTracks' (подобно тому, как вы объединяете видео вместе), или вам нужно, чтобы CALayers включали изображения в объединенное видео. Вопрос здесь: http://stackoverflow.com/questions/34937862/merge-videos-images-in-avmutablecomposition-using-avmutablecompositiontrack – Crashalot

1

У меня была проблема, что почти все визуализировалось отлично, а также изображения с CALayer и содержимым, установленным в CGImage. За исключением текста CGTextLayer, если я устанавливаю цвет фона для CGTextLayer, startTime и продолжительность, которая была отлично отображена - просто фактический текст не хотел появляться. Все было на симуляторе, затем я запустил его по телефону: И это было прекрасно.

Заключение: симулятор отображает приятные видео ... Пока вы не используете CATextLayer.

0

Моя проблема заключалась в том, что мне нужно было установить contentsGravity = kCAGravityBottomLeft - иначе мой текст был вне экрана.

 Смежные вопросы

  • Нет связанных вопросов^_^