本文介绍了从单元测试运行时,CATextLayer不会出现在AVMutableComposition中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最奇怪的事情是:从完整的应用程序运行此代码似乎一切正常,但是我一直在通过单元测试运行电影的创建,但仅在那儿它不起作用.试图弄清楚为什么...

我正在尝试使用AVMutableComposition组合视频+音频+文本,并将其导出到新视频.

I'm trying to combine video + audio + text using AVMutableComposition and export it to a new video.

我的代码基于WWDC '10的AVEditDemo

My code is based on the AVEditDemo from WWDC '10

我在CATextLayer中添加了紫色背景,因此我可以知道它已导出到电影中,但是没有显示任何文字...我尝试使用各种字体,位置,颜色定义,但没有任何帮助,因此我决定在此处发布代码,看看是否有人偶然发现类似内容并可以告诉我我所缺少的内容.

I added a purple background to the CATextLayer so I can know for a fact it is exported to the movie, but no text is shown... I tried playing with various fonts, position, color definitions, but nothing helped, so I decided to post the code here and see if anyone stumbled across something similar and can tell me what I'm missing.

这是代码(self.audio和self.video是AVURLAssets):

Here's the code (self.audio and self.video are 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 ...
}];

推荐答案

还需要进一步研究,但是AFAICT目前在AVMutableVideoComposition中的CATextLayer根本无法在逻辑单元测试目标中使用,并且必须从以下位置对该功能进行测试常规目标.

Further investigation is needed, but AFAICT right now CATextLayer inside an AVMutableVideoComposition simply doesn't work from within a logic unit tests target, and this feature must be tested from a regular target.

这篇关于从单元测试运行时,CATextLayer不会出现在AVMutableComposition中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-23 16:37