使用alpha合成2个视频

时间:2012-01-07 11:17:54

标签: objective-c cocoa avfoundation avcomposition avvideocomposition

AVFoundation允许您将2个资源(2个视频)“组合”为2个“曲目”,就像在Final Cut Pro中一样。

理论上说,我可以将两个视频叠加在一起,使用alpha,并查看两者。

我要么做错了,或者某处有错误,因为下面的测试代码虽然有点混乱,但明确表示我应该看到2个视频,而我只看到一个,如下所示:{{3} } - “蓝色”方块是IMG_1388.m4v

无论出于何种原因,IMG_1383.MOV永远不会显示。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], AVURLAssetPreferPreciseDurationAndTimingKey, nil];
AVMutableComposition *composition = [AVMutableComposition composition];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(4, 1));
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];

// Track B
NSURL *urlVideo2 = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/IMG_1388.m4v"];
AVAsset *video2 = [AVURLAsset URLAssetWithURL:urlVideo2 options:options];
AVMutableCompositionTrack *videoTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:0];
NSArray *videoAssetTracks2 = [video2 tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoAssetTrack2 = ([videoAssetTracks2 count] > 0 ? [videoAssetTracks2 objectAtIndex:0] : nil);
[videoTrack2 insertTimeRange:timeRange ofTrack:videoAssetTrack2 atTime:kCMTimeZero error:&error];

AVMutableVideoCompositionLayerInstruction *to = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack2];
[to setOpacity:.5 atTime:kCMTimeZero];
[to setTransform:CGAffineTransformScale(videoAssetTrack2.preferredTransform, .5, .5) atTime:kCMTimeZero];

// Track A
NSURL *urlVideo = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/IMG_1383.MOV"];
AVURLAsset *video = [AVURLAsset URLAssetWithURL:urlVideo options:options];
AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:1];
NSArray *videoAssetTracks = [video tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoAssetTrack = ([videoAssetTracks count] > 0 ? [videoAssetTracks objectAtIndex:0] : nil);
[videoTrack insertTimeRange:timeRange ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil];

AVMutableVideoCompositionLayerInstruction *from = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack];
[from setOpacity:.5 atTime:kCMTimeZero];

// Video Compostion
AVMutableVideoCompositionInstruction *transition = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
transition.backgroundColor = [[UIColor clearColor] CGColor];
transition.timeRange = timeRange;
transition.layerInstructions = [NSArray arrayWithObjects:to, from, nil];
videoComposition.instructions = [NSArray arrayWithObjects:transition,  nil];
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake(480, 360);


// Export
NSURL *outputURL = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/export.MOV"];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[[composition copy] autorelease] presetName:AVAssetExportPresetHighestQuality];
[exportSession setOutputFileType:@"com.apple.quicktime-movie"];
exportSession.outputURL = outputURL;
exportSession.videoComposition = videoComposition;
[exportSession exportAsynchronouslyWithCompletionHandler:nil];

// Player
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition];
playerItem.videoComposition = videoComposition;
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

你看到了什么问题吗?

此代码的“目标”是“记录”摄像机输入(视频1)和opengl输出(视频2)。我也尝试用“缓冲区”直接“组合”它们,但是我还是不成功:(原来AVFoundation不像我想象的那么简单。

2 个答案:

答案 0 :(得分:3)

看起来不错,除了这部分:

AVMutableVideoCompositionLayerInstruction *from = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack];
AVMutableVideoCompositionLayerInstruction *to = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack2];

您需要使用videoTrackvideoTrack2来构建图层说明,即添加到composition的曲目,而不是原始资源videoAssetTrack和{{1 }}。

此外,添加一个转换来旋转视频它有点棘手(就像基础知识之外的AVFoundation中的任何东西)。 我刚刚评论了这条线,让它播放了2个视频。

这是您修改的代码:

videoAssetTrack2

答案 1 :(得分:0)

我认为你错了。

视频文件可能包含多个数据流。例如,如果它是带声音的视频,则该文件将具有2个流,即音频流和视频流。另一个例子是音频环绕视频文件,其可以包括5个或更多个音频流和1个视频流。

与音频一样,大多数视频文件容器格式(mov,mp4等)都支持1个文件中的多个视频流,但事实上这并不意味着这些流将彼此有任何关系,它们只存储在同一个文件容器中。例如,如果您将使用QuickTime打开此类文件,您将获得与此类文件上的视频流一样多的窗口。

无论如何,视频流不会以这种方式“混合”。 你想要实现的是与视频流的信号处理有关,我真的建议你阅读更多关于它的信息。

如果您不需要将视频数据“混合”到一个文件中,您可能希望使用MPMediaPlayers将两个视频文件相互显示。请记住,处理视频数据通常是一个CPU密集型问题,您可能(有时)使用现在的iOS设备无法解决这个问题。