2012-04-23 111 views
11

編輯:最奇怪的事情:它似乎是從完整的應用程序運行此代碼時,一切正常,但我總是運行從我的電影創作單元測試,只有它沒有工作。試圖找出爲什麼...從單元測試運行時,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 – 2012-04-28 15:30:25

+0

謝謝,我做的事情幾乎相同那裏提到了什麼。如果有人發現我的代碼和相關答案中的代碼之間的重要區別,我會非常感激。 – yonix 2012-04-29 08:19:33

+0

您是否嘗試設置字體大小? – 2012-04-30 00:55:56

回答

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 2016-01-22 03:00:51

1

我有問題,幾乎所有的東西都渲染得很好,還有CALayer和內容設置爲CGImage的圖像。除了CGTextLayer文本,如果我爲CGTextLayer設置了背景顏色,則可以完美呈現beginTime和duration - 只是實際文本不想出現。 這些都在模擬器上,然後我在手機上運行它:它非常完美。

結論:模擬器渲染漂亮的視頻......直到你使用CATextLayer。

0

我的問題是,我需要設置contentsGravity = kCAGravityBottomLeft - 否則我的文本離開了屏幕。

相關問題