2012-04-23 12 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今AVMutableVideoComposition内部CATextLayerは、単に論理ユニットテスト内から動作しません。この機能は通常のターゲットからテストする必要があります。

1

私は別の文脈で同じ問題に遭遇しました。私の場合は、AVMutableCompositionの準備をバックグラウンドスレッドに移しました。その準備の部分をメインキュー/スレッドに戻すことで、CATextLayerオーバーレイが正常に動作します。

これはユニットテストのコンテキストには当てはまりませんが、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を設定する必要があるということでした。それ以外の場合は、テキストが画面外になっていました。

関連する問題