ios - 没有 AVAsset 的纯色的 AVMutableComposition

标签 ios objective-c avfoundation

这是我的最终目标:我想使用 AVVideoCompositionCoreAnimationTool 从 Core Animation 创建视频。 我不会在此合成中使用现有的 AVAsset。

我的问题是,我如何使用 AVMutableComposition 制作一段在给定时间内具有静态纯色的视频?弄清楚之后,我可以添加动画。

这是我的代码:

- (void)exportVideo {

AVMutableComposition *mixComposition = [AVMutableComposition composition];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(10, 600));
[mixComposition insertEmptyTimeRange:timeRange];

AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertEmptyTimeRange:timeRange];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = timeRange;
mainInstruction.backgroundColor = [UIColor blueColor].CGColor;

AVMutableVideoComposition *mainComposition = [AVMutableVideoComposition videoComposition];

mainComposition.renderSize = CGSizeMake(500, 500);
mainComposition.instructions = [NSArray arrayWithObject:mainInstruction];
mainComposition.frameDuration = CMTimeMake(1, 30);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"FinalVideo-%d.mov",arc4random() % 1000]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                  presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = url;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = mainComposition;

[exporter exportAsynchronouslyWithCompletionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self exportDidFinish:exporter];
    });
}];

}

我知道您必须向 mixComposition 添加至少一个轨道,所以我添加了一个视频轨道并插入了一个空的时间范围,但是当我调用 exportAsynchronouslyWithCompletionHandler 时,从未调用处理程序.在我调用 export 并观察导出器的状态为 AVAssetExportSessionStatusExporting 之后,我可以在任意时间内添加一个 dispatch_after

我做错了什么?

最佳答案

几个月前玩过这个之后,我发现让它工作的唯一可靠方法是在 AVMutableCompositionTrack 中使用一个简短的空白视频,然后用所需的图层覆盖它。

由于模拟器中的错误,我大约一个月前将项目上传到 GitHub。您可以下载空白视频here ,如果你愿意的话。

-(void)exportVideo
{
    CGSize renderingSize = CGSizeMake(640, 360); // The desired size of your video
    float displayDuration = 2.0f; //The duration of the desired video, in seconds

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *myPathDocs =  [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"FinalVideo-%d.mov",arc4random() % 1000]];
    NSURL *url = [NSURL fileURLWithPath:myPathDocs];

    NSError *error;
    [[NSFileManager defaultManager] removeItemAtURL:url error:&error];

    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 *trackUrl = [NSURL fileURLWithPath:path];
    AVAsset *asset = [AVAsset assetWithURL:trackUrl];
    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.backgroundColor = [UIColor blueColor].CGColor;
    imageLayer.contentsGravity = kCAGravityResizeAspectFill;
    [parentLayer addSublayer:imageLayer];

    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(displayDuration, 600));
    videoComposition.instructions = @[instruction];

    exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetHighestQuality];
    exporter.outputURL = url;
    exporter.videoComposition = videoComposition;
    exporter.outputFileType= AVFileTypeMPEG4;
    exporter.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(displayDuration, 600));
    exporter.shouldOptimizeForNetworkUse = YES;

    [exporter exportAsynchronouslyWithCompletionHandler:^(void){
        dispatch_async(dispatch_get_main_queue(), ^{
            [self exportDidFinish:exporter];
        });
    }];
}

关于ios - 没有 AVAsset 的纯色的 AVMutableComposition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20871328/

相关文章:

ios - 无需在 View Controller 中使用 loadFromNib 即可快速使用 Nib 自定义 UIView

ios - Firebase 云消息传递中是否有适用于 iOS 的 ttl "time to live"的替代方案?

ios - 如何通过单击按钮移动到 iOS 中的另一个 View Controller ?

ios - iOS 中的蓝牙 LE 和 ANCS

ios - CGBitmapContextCreate 无效数据字节/行

ios - 在 iOS/Swift 中从 gs_instruments 播放单个 midi 音符

ios - IOS平台是否可以在拨出或来电时显示图片或视频?

objective-c - NSTextview:如何获取插入点的字形矩形?自定义 TextView ?

ios - AVFoundation 位置音频无法在 iOS 设备上运行

ios -/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 失败,退出代码 1