我有两个视频,其中一个是带透明背景的叠加视频(爆炸视频,我正在尝试将其添加到视频中)。当我尝试使用AVMutableComposition将它们组合时,我发现叠加视频的alpha通道被忽略了。基本上我只看到第二个视频(黑色背景而不是透明背景)。
为了测试,我向叠加视频添加了0.9的不透明度,只是为了确保它们正确合并,并且结果显示主视频在叠加视频下方(这当然不是我想要的,但证明了合成起作用)。有什么办法使第二个视频的alpha通道正常工作吗?
为了测试,我向叠加视频添加了0.9的不透明度,只是为了确保它们正确合并,并且结果显示主视频在叠加视频下方(这当然不是我想要的,但证明了合成起作用)。有什么办法使第二个视频的alpha通道正常工作吗?
NSError* error = nil;
AVMutableComposition *comp = [AVMutableComposition composition];
AVMutableCompositionTrack* videoCompTrack = [comp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:0];
AVMutableCompositionTrack* videoCompTrack2 = [comp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:1];
AVMutableCompositionTrack* audioCompTrack = [comp addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// main video
AVURLAsset* videoAssetMain = [AVURLAsset URLAssetWithURL:url1 options:nil];
NSArray* tracks = [videoAssetMain tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack* videoTrackMain = [tracks firstObject];
tracks = [videoAssetMain tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack* audioTrackMain = [tracks firstObject];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, videoTrackMain.timeRange.duration);
// overlay video with alpha channel
AVURLAsset* videoAssetOver = [AVURLAsset URLAssetWithURL:url2 options:nil];
tracks = [videoAssetOver tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack* videoTrackOver = [tracks firstObject];
[videoCompTrack insertTimeRange:timeRange ofTrack:videoTrackMain atTime:kCMTimeZero error:&error];
[videoCompTrack2 insertTimeRange:timeRange ofTrack:videoTrackOver atTime:kCMTimeZero error:&error];
[audioCompTrack insertTimeRange:timeRange ofTrack:audioTrackMain atTime:kCMTimeZero error:&error];
AVMutableVideoCompositionLayerInstruction *inst1 = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompTrack];
[inst1 setOpacity:1 atTime:kCMTimeZero];
AVMutableVideoCompositionLayerInstruction *inst2 = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompTrack2];
// adding translucency to test that bottom video is there
// [inst2 setOpacity:0.9 atTime:kCMTimeZero];
// stretch overlay video on top of main video
CGAffineTransform scale = CGAffineTransformMakeScale(videoTrackMain.naturalSize.width/videoTrackOver.naturalSize.width, videoTrackMain.naturalSize.height/videoTrackOver.naturalSize.height);
[inst2 setTransform:scale atTime:kCMTimeZero];
AVMutableVideoCompositionInstruction *trans = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
trans.backgroundColor = [UIColor clearColor].CGColor;
trans.timeRange = timeRange;
trans.layerInstructions = [NSArray arrayWithObjects:inst2,inst1, nil];
AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition];
videoComp.instructions = [NSArray arrayWithObjects:trans,nil];
videoComp.frameDuration = CMTimeMake(1, 30);
videoComp.renderSize = comp.naturalSize;
AVAssetExportSession* expSession = [[AVAssetExportSession alloc] initWithAsset:comp presetName:AVAssetExportPresetHighestQuality];
NSString* newVideoPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output_final.mov"];
if ([[NSFileManager defaultManager] fileExistsAtPath:newVideoPath]) {
[[NSFileManager defaultManager] removeItemAtPath:newVideoPath error:&error];
}
expSession.outputURL = [NSURL fileURLWithPath:newVideoPath];
expSession.outputFileType = AVFileTypeQuickTimeMovie;
expSession.videoComposition = videoComp;
[expSession exportAsynchronouslyWithCompletionHandler:^{
if (delegate) {
[delegate videoProcessor:self didFinish:expSession.outputURL];
}
}];