【问题标题】:Compositing 2 videos on top of each other with alpha使用 alpha 将 2 个视频叠加在一起
【发布时间】:2012-01-07 11:17:53
【问题描述】:

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

理论上说,我可以将 2 个视频叠加在一起,带有 alpha 版本,并且可以同时查看。

要么我做错了,要么某处有错误,因为以下测试代码虽然有点混乱,但清楚地表明我应该看到 2 个视频,而我只看到一个,如下所示:http://lockerz.com/s/172403384 - - “蓝色”方块是 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)。我还尝试使用 Buffers 等“直接”“组合”它们,但我也没有成功 :( 事实证明 AVFoundation 没有我想象的那么简单。

【问题讨论】:

  • 你好@StuFF mc 我想将多个视频与过渡合并我已经使用了来自gist.github.com/stuffmc/1572592/…的代码但是我无法在文档目录中获取输出文件并且我使用了djromero i> 回答,但它也不起作用请帮助我任何建议。

标签: objective-c cocoa avfoundation avcomposition avvideocomposition


【解决方案1】:

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

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

您需要使用videoTrackvideoTrack2 来构建层指令,即添加到composition 的轨道,而不是原始资产videoAssetTrackvideoAssetTrack2

此外,添加一个转换来旋转视频有点棘手(就像 AVFoundation 中的任何基础知识一样)。 我刚刚注释掉了这条线,让它可以播放 2 个视频。

这是您的修改后的代码:

NSError *error = nil;
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 = [[NSBundle mainBundle] URLForResource:@"b" withExtension:@"mov"];        
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:videoTrack2];
[to setOpacity:.5 atTime:kCMTimeZero];
//[to setTransform:CGAffineTransformScale(videoAssetTrack2.preferredTransform, .5, .5) atTime:kCMTimeZero];

// Track A
NSURL *urlVideo = [[NSBundle mainBundle] URLForResource:@"a" withExtension:@"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:videoTrack];
[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 = composition.naturalSize; // CGSizeMake(480, 360);

【讨论】:

  • 我还不能让它工作(你的代码),但是......我觉得很奇怪,我必须添加“videoTrack”,这是一个AVMutableCompositionTrack*,其中文档/标题明确声明-[videoCompositionLayerInstructionWithAssetTrack:(AVAssetTrack *)track(所以参数应该是AVAssetTrack*我的 videoAssetTrack 是。不过感谢您的帮助!最后,我终于按照说明“逐帧”“合成”了两个视频在devforums.apple.com/message/601194#601194
  • AVMutableCompositionTrack 是 AVAssetTrack 的子类。您需要对合成中的轨道(videoTrack 和 videoTrack2)进行说明,否则对结果没有影响。
  • 真的。用 my 运行你的代码 :) 视频给了我-[AVPlayerItem setVideoComposition:] video composition must have a positive renderSize。您使用哪个代码在 AVPlayerLayer 上“显示”视频?
  • 播放器代码是标准的,和你的类似。您是否复制了最后一行:videoComposition.renderSize = composition.naturalSize;
  • 您是否能够制作一个包含两个视频的视频?让我们知道您为实现这一目标所做的更改。
【解决方案2】:

我认为你搞错了。

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

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

无论如何,视频流不会以这种方式“混合”。 您要实现的目标与视频流的信号处理有关,我真的建议您阅读更多相关内容。

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

【讨论】:

  • 他显然是在尝试将两个视频叠加在一起并为其添加不透明度,以便您可以看到底层视频。如果您建议该作品只有一个视频轨道,您如何将这两个轨道添加到作曲家进行混音?
猜你喜欢
  • 1970-01-01
  • 2018-09-04
  • 2016-05-18
  • 1970-01-01
  • 2019-05-30
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
相关资源
最近更新 更多