如何在AVMutableComposition中同时为多个视频图层设置动画?

时间:2015-02-26 00:13:20

标签: ios video core-animation avfoundation avmutablecomposition

我正在编写一段代码,用于在iOS设备上生成多个图像和多个视频的幻灯片视频。我能够通过一个视频和多个图像来实现这一目标,但我无法弄清楚如何将其增强到多个视频。

这是the sample video我能用一个视频和两个图像生成。

这是准备出口商的主要例程。

// Prepare the temporary location to store generated video
NSURL * urlAsset = [NSURL fileURLWithPath:[StoryMaker tempFilePath:@"mov"]];

// Prepare composition and _exporter
AVMutableComposition *composition = [AVMutableComposition composition];
AVAssetExportSession* exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = urlAsset;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = [self _addVideo:composition time:timeVideo];

这是_addVideo:time:方法,它创建了videoLayer。

-(AVVideoComposition*) _addVideo:(AVMutableComposition*)composition time:(CMTime)timeVideo {
    AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.renderSize = _sizeVideo;
    videoComposition.frameDuration = CMTimeMake(1,30); // 30fps
    AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,timeVideo) ofTrack:_baseVideoTrack atTime:kCMTimeZero error:nil];

    // Prepare the parent layer
    CALayer *parentLayer = [CALayer layer];
    parentLayer.backgroundColor = [UIColor blackColor].CGColor;
    parentLayer.frame = CGRectMake(0, 0, _sizeVideo.width, _sizeVideo.height);

    // Prepare images parent layer
    CALayer *imageParentLayer = [CALayer layer];
    imageParentLayer.frame = CGRectMake(0, 0, _sizeVideo.width, _sizeVideo.height);
    [parentLayer addSublayer:imageParentLayer];

    // Specify the perspecrtive view
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0 / imageParentLayer.frame.size.height;
    imageParentLayer.sublayerTransform = perspective;

    // Animations
    _beginTime = 1E-10;
    _endTime = CMTimeGetSeconds(timeVideo);

    CALayer* videoLayer = [self _addVideoLayer:imageParentLayer];
    [self _addAnimations:imageParentLayer time:timeVideo];

    videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool      videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

    // Prepare the instruction
    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    {
        instruction.timeRange = CMTimeRangeMake(kCMTimeZero, timeVideo);
        AVAssetTrack *videoTrack = [[composition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
        [layerInstruction setTransform:_baseVideoTrack.preferredTransform atTime:kCMTimeZero];
        instruction.layerInstructions = @[layerInstruction];
    }
    videoComposition.instructions = @[instruction];
    return videoComposition;
} 

_addAnimation:time:方法添加图像图层,并安排所有图层的动画,包括_videoLayer。

到目前为止一切正常。

但是,我无法弄清楚如何将第二个视频添加到此幻灯片中。

AVFoundation编程指南中的示例使用多个视频合成指令(AVMutableVideoCompositionInstruction)来合并两个视频,但它只是将它们呈现为单个CALayer对象,该对象在videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:inLayer:method(AVVideoCompositionCoreAnimationTool)中指定。

我想将两个视频轨道渲染成两个独立的层(layer1和layer2),并分别为它们设置动画,就像我在处理与图像相关的图层一样。

1 个答案:

答案 0 :(得分:0)

我也遇到了这个问题,想制作多个视频的动画。我发现<Container style={{ backgroundColor:"#f4f4f4" }}>可以接受多个视频层,但是要注意的是它们是同一视频的多个实例。因此,我的解决方法是制作一个大视频,将2个视频彼此并排放置,并使用遮罩在其自己的图层中显示每个视频。

这是视频层的外观: the inability to create a MultiBinding for "all implementations of a given interface" without having to explicitly declare them

这是在遮罩中使用该层显示每个视频的粗略概念: videos1 videos2

这是我的代码,您只需要2个示例视频即可使其工作:

AVVideoCompositionCoreAnimationTool