CALayer.contents在AVMutableComposition中不能正确渲染

我有一个非常简单的方法,用一个静态背景图像来生成一个video,该静态背景图像覆盖了整个video的组成部分,以及一个位于video底部的较小的,部分透明的图像(水印风格)。

背景图像正确呈现,看起来与图像查看器中的完全相同。 然而,应该在video底部呈现的图像是倾斜/扭曲的。

源代码可以在这里下载到GitHub上。

我的代码的预期输出(所需video输出的样机):

视频的预期输出

我的代码的实际输出(从iOS模拟器部分截图):

我的视频输出的实际截图

正如您所看到的,页脚图像呈45度倾斜并呈波浪状。

以下是我目前用来生成video的代码。 我已经尝试过所有可能的contentGravity组合,但没有运气。 我见过的其他每个例子都只是将CGImageRef设置为图层的contents然后将boundspositionanchorPoint为适当的值。 我还没有看到其他任何设置其他属性的例子。 我已经阅读了几乎所有的AVFoundation的文件,看看是否有设置,我错过了,但我还没有遇到任何明显的事情。

任何build议将不胜感激。 谢谢!

接口声明:

 CGSize _renderingSize; float _displayDuration; AVMutableComposition *mutableComposition; AVMutableVideoComposition *videoComposition; AVMutableCompositionTrack *mutableCompositionVideoTrack; AVAssetExportSession *exporter; 

ViewDidLoad设置:

 _renderingSize = CGSizeMake(640, 360); _displayDuration = 2.0; 

渲染代码块:

  mutableComposition = [AVMutableComposition composition]; mutableCompositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; videoComposition = [AVMutableVideoComposition videoComposition]; videoComposition.renderSize = _renderingSize; videoComposition.frameDuration = CMTimeMake(1, 30); CALayer *parentLayer = [CALayer layer]; CALayer *videoLayer = [CALayer layer]; parentLayer.frame = CGRectMake(0, 0, videoComposition.renderSize.width, videoComposition.renderSize.height); videoLayer.frame = CGRectMake(0, 0, videoComposition.renderSize.width, videoComposition.renderSize.height); [parentLayer addSublayer:videoLayer]; videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; NSString *path = [[NSBundle mainBundle] pathForResource:@"blank_1080p" ofType:@"mp4"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAsset *asset = [AVAsset assetWithURL:url]; AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; [mutableCompositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,CMTimeMakeWithSeconds(_displayDuration, 600)) ofTrack:track atTime:kCMTimeZero error:nil]; CALayer *imageLayer = [CALayer layer]; imageLayer.bounds = parentLayer.frame; imageLayer.anchorPoint = CGPointMake(0.5, 0.5); imageLayer.position = CGPointMake(CGRectGetMidX(imageLayer.bounds), CGRectGetMidY(imageLayer.bounds)); imageLayer.contents = (id)[UIImage imageNamed:@"background.png"].CGImage; imageLayer.contentsGravity = kCAGravityResizeAspectFill; [parentLayer addSublayer:imageLayer]; UIImage *testImage = [UIImage imageNamed:@"bannerTextLayer.png"]; CALayer *footerLayer = [CALayer layer]; footerLayer.bounds = CGRectMake(0, 0, 540, 40); footerLayer.anchorPoint = CGPointMake(0.5, 0.5); footerLayer.position = CGPointMake(CGRectGetMidX(footerLayer.bounds), CGRectGetMidY(footerLayer.bounds)); footerLayer.contents = (id)testImage.CGImage; footerLayer.contentsGravity = kCAGravityResizeAspectFill; [parentLayer addSublayer:footerLayer]; AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(_displayDuration, 600)); videoComposition.instructions = @[instruction]; exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetHighestQuality]; exporter.outputURL = videoURL ; exporter.videoComposition = videoComposition; exporter.outputFileType= AVFileTypeMPEG4; exporter.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(_displayDuration, 600)); exporter.shouldOptimizeForNetworkUse = YES; [exporter exportAsynchronouslyWithCompletionHandler:^(void){ switch (exporter.status) { case AVAssetExportSessionStatusFailed:{ NSLog(@"Fail: %@", exporter.error); break; } case AVAssetExportSessionStatusCompleted:{ NSLog(@"Success"); dispatch_async(dispatch_get_main_queue(), ^{ if (self.moviePlayer) [self.moviePlayer.view removeFromSuperview]; self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL]; self.moviePlayer.view.frame = CGRectMake(0, 0, 320, 180); [self.moviePlayer setControlStyle:MPMovieControlStyleNone]; [self.previewView addSubview:self.moviePlayer.view]; [self.moviePlayer play]; }); break; } default: break; } }]; 

iOS模拟器7.0及以上版本有使用AVExportSession渲染video的这个错误。 如果你将在实际的设备上testing这个,输出将是你想要的,它不会歪斜。