CALayer.contents无法在AVMutableComposition中正确呈现 [英] CALayer.contents not rendering correctly in AVMutableComposition

查看:195
本文介绍了CALayer.contents无法在AVMutableComposition中正确呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的方法,可以生成一个视频,其中包含覆盖整个视频合成的静态背景图像,以及位于视频底部的较小的,部分透明的图像(水印样式)。

I have a very simple method that generates a video with a static background image which covers the entire video composition and a smaller, partially transparent image (watermark style) that's located at the bottom of the video.

背景图像渲染正确,与图像查看器中的外观完全相同。但是,应该在视频底部呈现的图像会出现偏斜/扭曲。

The background image renders correctly and appears exactly the same as it looks in an image viewer. However, the image that's supposed to be rendered at the bottom of the video is skewed/distorted.

可以在GitHub上下载源代码。

The source can be downloaded here, on GitHub.

预期输出我的代码(所需视频输出的模型):

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

如您所见,页脚图像以45度角和一点波浪形倾斜。

As you can see, the footer image appears skewed at a 45 degree angle and a little wavy.

以下是我目前用于生成视频的代码。我已经尝试了每个可能的内容组合的重力为页脚图像,没有运气。我见过的每个其他示例只是将CGImageRef设置为图层的内容然后设置边界 position anchorPoint 到适当的值。我还没有看到任何其他设置任何其他属性的示例。我已经阅读了几乎所有关于AVFoundation的文档,看看是否有我失踪的设置,但我还没有遇到任何明显的问题。

Below is the code that I'm currently using to generate the video. I've tried every possible combination of contentsGravity for the footer image, with no luck. Every other example that I've seen simply sets a CGImageRef to the layer's contents then sets the bounds, position and anchorPoint to their appropriate values. I haven't seen any other examples that set any other properties. I've read through almost all of the documentation for the AVFoundation to see if there setting that I'm missing, but I haven't come across anything obvious yet.

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

Any suggestions would be greatly appreciated. Thanks!

接口声明:

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。如果你将在实际设备上测试它,输出将是你想要的,它不会倾斜。

iOS Simulator 7.0 and above has this bug of rendering video using AVExportSession. If you will test this on actual device, the output will be as you want, it will not skew.

这篇关于CALayer.contents无法在AVMutableComposition中正确呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆