我正在使用AVFoundation为视频添加水印,并使用另一个具有透明度的视频。我已设法使用以下代码将一个视频叠加在另一个视频之上,但只要我开始使用具有透明度的资产,导出就会失败而没有任何有用的错误。
This link谈到PreRes 4444是AVFoundation在alpha通道方面唯一支持的编解码器,但我找不到任何官方文档。我目前尝试添加为叠加层的文件是H.264编码的mp4,在阅读Learning AVFoundation之后,它似乎是最佳选择,其中声明
ProRes编解码器仅在OS X上可用。如果您正在开发 仅适用于iOS,H264是镇上唯一的游戏。
我总是可以回退添加动画层而不是视频叠加层,但如果没有解决方案,我会感到惊讶。
- (void)addWatermarkToAsset:(NSURL *)assetURL completionHandler:(void (^)(NSURL *videoURL))handler
{
AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
// This asset contains an alpha channel, and has a shorter duration than videoAsset
NSURL *animationUrl = [[NSBundle mainBundle] URLForResource:@"InstagramAnimation" withExtension:@"mp4"];
AVURLAsset *animationAsset = [AVURLAsset URLAssetWithURL:animationUrl options:nil];
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *animationTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[animationTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, animationAsset.duration)
ofTrack:[[animationAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
CGAffineTransform scale = CGAffineTransformMakeScale(0.7f,0.7f);
CGAffineTransform move = CGAffineTransformMakeTranslation(230,230);
[videoLayerInstruction setTransform:CGAffineTransformConcat(scale, move) atTime:kCMTimeZero];
AVMutableVideoCompositionLayerInstruction *animationLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:animationTrack];
CGAffineTransform secondScale = CGAffineTransformMakeScale(1.2f,1.5f);
CGAffineTransform secondMove = CGAffineTransformMakeTranslation(0,0);
[animationLayerInstruction setTransform:CGAffineTransformConcat(secondScale, secondMove) atTime:kCMTimeZero];
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videoLayerInstruction, animationLayerInstruction, nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
mainCompositionInst.renderSize = videoTrack.naturalSize;
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 = mainCompositionInst;
[exporter exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:exporter];
});
}];
}
答案 0 :(得分:1)
我是通过做一个这样做的
1. H264内的自定义透明格式和一个
2.自定义透明度格式的自定义(perforce)合成器
自定义格式是一个“高”视频,每个颜色框架都在黑色和白色蒙版的正上方。
合成器从水印中获取帧并将文件加水印,组合它们,并将结果写入第3个文件。 每帧的每个像素被解释为YUV值,一个用作颜色,另一个用作遮罩,并与背景帧组合。
为了加快速度,合成器是OpenGL像素着色器+ TextureCaches,虽然今天你使用的是Metal和CVMetalTextureCache
。